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) almost 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) almost 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) almost 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) almost 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) almost 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 almost 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) almost 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 over 9 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.