Aliasing to an inherited method


#1

I tried to modify Daniel S.'s code (in response to the recent
“abstract class” thread) to not have an additional method dispatch.
This line here:

def self.new(*args, &block)
new(*args, &block)
end

cries out for a direct alias, to me. Unfortunately, what I hoped would
work didn’t. It looks like #alias_method only looks for methods on the
current class; it’s not able to alias to a method from an ancestor
class.

class Class
alias_method :new, :new
end

module NonInstantiable
def self.included(klass)
super
klass.module_eval {
def self.inherited( subklass )
subklass.module_eval {
puts “Is new available? #{method( :new )}”
alias_method :new, :new
}
end
}
end
end

class BaseKlass
include NonInstantiable
end

class SubKlass < BaseKlass; end

p SubKlass.new
p BaseKlass.new

#=> Is new available? #<Method: Class#new>
#=> tmp.rb:12:in alias_method': undefined methodnew’ for class
`SubKlass’ (NameError)

Is this behavior desirable, a necessary evil, or an oversight?


#2

#new is a class method so you got to get up in that class level.

class Class
class << self
alias_method :new, :new
end
end


#3

Oops, my bad. You’re right Daniel. I didn’t even notice that was class
Class.


#4

Okay, so put the class-level where it beleongs:

  puts "Is __new__ available? #{method( :__new__ )}"
  class << self
    alias_method :new, :__new__
  end

T.


#5

Trans wrote:

#new is a class method so you got to get up in that class level.

class Class
class << self
alias_method :new, :new
end
end

Actually, the instance methods defined in Class become class methods in
every instance of it (classes)

class Class
def foo; "bar; end
end

Integer.foo => “bar”

It’s a bit confusing, but just think of every class in Ruby as an
instance of Class.

Cheers,
Daniel