Project

General

Profile

Actions

Feature #6452

open

Allow extend to override class methods

Added by rosenfeld (Rodrigo Rosenfeld Rosas) over 12 years ago. Updated about 4 years ago.

Status:
Assigned
Target version:
-
[ruby-core:45128]

Description

module A
  def self.a
    'a1'
  end
end

module B
  def a
    'a2'
  end

  def b
    'b'
  end
end

A.extend B

assert A.a == 'a2' # this is the change I'm proposing - currently it is 'a1'
assert A.b == 'b'

Would this change be possible for 3.0?


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #1102: Prepend ModuleClosednobu (Nobuyoshi Nakada)02/04/2009Actions

Updated by mame (Yusuke Endoh) over 12 years ago

  • Status changed from Open to Assigned

Hello,

rosenfeld (Rodrigo Rosenfeld Rosas) wrote:

Would this change be possible for 3.0?

Why don't you add a new method instead of changine an existing one?

What you want is allowed by a feature planned for Ruby 2.0 called
Module#prepend:

class << A
prepend B
end

See #1102 and the thread starting with [ruby-core:25208].
If you want to do so without opening singleton class, please propose
a new method name.

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 12 years ago

I'm not sure if prepend would have the same effect. I was expecting to call "super" in B and it would call A.a.

Does it make sense?

I don't really care if this would have another method name.

Would you mind to explain why the current behavior is useful instead of doing what I'm proposing?

I really don't understand why it was implemented this way...

Updated by mame (Yusuke Endoh) over 12 years ago

Hello,

2012/5/19 rosenfeld (Rodrigo Rosenfeld Rosas) :

Would you mind to explain why the current behavior is useful instead of doing what I'm proposing?

Just example:

module GenericConnection
def connect(domain)
TCPSocket.open(domain)
end
end

class Google
extend GenericConnection
def self.connect
super("www.google.com")
end
end

class Twitter
extend GenericConnection
def self.connect
super("www.twitter.com")
end
end

I really don't understand why it was implemented this way...

You may think so because you declared modules and methods in weird
order.
You should declare a smaller, more generic, or more independent
module first, and then a bigger one by using already-defined ones.
Do you still expect 'a2' for the following code?

module B
def a
'a2'
end
end

module A
extend B
def self.a
'a1'
end
end

p A.a #=> 'a1'

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 12 years ago

Yeah, sorry I should have thought about this before.

You're right, for normal usage the current behavior is more useful indeed.

I was willing to patch a class from a third-party library, that is why I wanted my module method to take precedence.

Would you consider to add a new method for such case? And an equivalent one for include as well?

Should I open a new ticket and close this one?

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 10 years ago

Would Module.preextend be a good name for that? It would indicate it's similar to prepend but applied to extend...

Updated by Anonymous over 10 years ago

Rodrigo Rosenfeld Rosas wrote:

Would Module.preextend be a good name for that? It would indicate it's similar to prepend but applied to extend...

Does this do what you want to do?

class Object
def preextend m
singleton_class.prepend m
end
end

If yes, then there is no urgent need to ask for a new feature from the core team.

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 10 years ago

Hi Boris,

there's indeed no urgency in asking for such a feature but I don't think it's a required reason for a feature request, is it?

But thanks for the suggested implementation, really useful.

Updated by Anonymous about 10 years ago

There is the problem of feature creep, like classes becoming harder and harder to learn... That's what I meant ny no urgent need. I might be mistaken.

Actions #9

Updated by naruse (Yui NARUSE) about 4 years ago

  • Target version deleted (3.0)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0