Feature #6452

Allow extend to override class methods

Added by Rodrigo Rosenfeld Rosas almost 2 years ago. Updated almost 2 years ago.

[ruby-core:45128]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:-
Target version:Next Major

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

Related to ruby-trunk - Feature #1102: Prepend Module Closed 02/04/2009

History

#1 Updated by Yusuke Endoh almost 2 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 .
If you want to do so without opening singleton class, please propose
a new method name.

Yusuke Endoh mame@tsg.ne.jp

#2 Updated by Rodrigo Rosenfeld Rosas almost 2 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...

#3 Updated by Yusuke Endoh almost 2 years ago

Hello,

2012/5/19 rosenfeld (Rodrigo Rosenfeld Rosas) rr.rosas@gmail.com:

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 mame@tsg.ne.jp

#4 Updated by Rodrigo Rosenfeld Rosas almost 2 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?

Also available in: Atom PDF