Project

General

Profile

Actions

Feature #6452

open

Allow extend to override class methods

Added by rosenfeld (Rodrigo Rosenfeld Rosas) almost 12 years ago. Updated over 3 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) 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

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) :

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

Actions #9

Updated by naruse (Yui NARUSE) over 3 years ago

  • Target version deleted (3.0)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0