Feature #6452
openAllow extend to override class methods
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?
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 mame@tsg.ne.jp
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) 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
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.