在Ruby中,如何从类的实例中调用类方法?说我有
class Truck
def self.default_make
# Class method.
"mac"
end
def initialize
# Instance method.
Truck.default_make # gets the default via the class's method.
# But: I wish to avoid mentioning Truck. Seems I'm repeating myself.
end
end
Truck.default_make行检索默认值。但有办法不提卡车吗?似乎应该有。
下面是一种如何在这种情况下实现作为self.class的_class方法的方法。注意:不要在产品代码中使用它,这是出于兴趣考虑:)
你能在Ruby调用者的上下文中评估代码吗?还有http://rubychallenger.blogspot.com.au/2011/07/caller-binding.html
# Rabid monkey-patch for Object
require 'continuation' if RUBY_VERSION >= '1.9.0'
class Object
def __; eval 'self.class', caller_binding; end
alias :_class :__
def caller_binding
cc = nil; count = 0
set_trace_func lambda { |event, file, lineno, id, binding, klass|
if count == 2
set_trace_func nil
cc.call binding
elsif event == "return"
count += 1
end
}
return callcc { |cont| cc = cont }
end
end
# Now we have awesome
def Tiger
def roar
# self.class.roar
__.roar
# or, even
_class.roar
end
def self.roar
# TODO: tigerness
end
end
也许正确的答案是为Ruby提交一个补丁:)
下面是一种如何在这种情况下实现作为self.class的_class方法的方法。注意:不要在产品代码中使用它,这是出于兴趣考虑:)
你能在Ruby调用者的上下文中评估代码吗?还有http://rubychallenger.blogspot.com.au/2011/07/caller-binding.html
# Rabid monkey-patch for Object
require 'continuation' if RUBY_VERSION >= '1.9.0'
class Object
def __; eval 'self.class', caller_binding; end
alias :_class :__
def caller_binding
cc = nil; count = 0
set_trace_func lambda { |event, file, lineno, id, binding, klass|
if count == 2
set_trace_func nil
cc.call binding
elsif event == "return"
count += 1
end
}
return callcc { |cont| cc = cont }
end
end
# Now we have awesome
def Tiger
def roar
# self.class.roar
__.roar
# or, even
_class.roar
end
def self.roar
# TODO: tigerness
end
end
也许正确的答案是为Ruby提交一个补丁:)
如果你可以访问委托方法,你可以这样做:
[20] pry(main)> class Foo
[20] pry(main)* def self.bar
[20] pry(main)* "foo bar"
[20] pry(main)* end
[20] pry(main)* delegate :bar, to: 'self.class'
[20] pry(main)* end
=> [:bar]
[21] pry(main)> Foo.new.bar
=> "foo bar"
[22] pry(main)> Foo.bar
=> "foo bar"
或者,如果你有一个或两个以上的方法,你想委托给类和实例:
[1] pry(main)> class Foo
[1] pry(main)* module AvailableToClassAndInstance
[1] pry(main)* def bar
[1] pry(main)* "foo bar"
[1] pry(main)* end
[1] pry(main)* end
[1] pry(main)* include AvailableToClassAndInstance
[1] pry(main)* extend AvailableToClassAndInstance
[1] pry(main)* end
=> Foo
[2] pry(main)> Foo.new.bar
=> "foo bar"
[3] pry(main)> Foo.bar
=> "foo bar"
提醒一句:
不要只是随机地将所有不改变状态的东西委托给类和实例,因为这会开始遇到奇怪的名称冲突问题。这样做是有节制的,只有在你检查没有其他压扁。