Ruby 中的代表团
Delegation in Ruby
我有一个 class Klass
,它的构造函数接受一个参数。我们应该能够调用此对象上未在 Klass
.
中定义的方法
我们可以链接多个方法,但最后,我们必须使用 Klass#result
来获得如下结果:
Klass.new(5).pred.pred.result
这里的输出应该是3
。我尝试在 Klass
中使用 method_missing
并在对象的 class 中使用 send
,但如果没有我必须使用的 result
方法,那也可以工作。有人可以解释如何通过委派来完成吗?
你可以这样做:
class Klass
def initialize(number)
@number = number
end
def result
@number
end
def method_missing(method_name, *arguments, &block)
if @number.respond_to?(method_name)
@number = @number.method(method_name).call(*arguments, &block)
return self
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
# be sure to implement this...
end
end
puts Klass.new(5).pred.pred.result # => 3
但这是有问题的。在此特定示例中,由于#pred return 是一个新对象(它不会修改调用它的对象),我们必须将实例变量重新分配给结果。它适用于 return 新整数的 pred 和其他方法,但整数上的一些方法不 return 一个整数(例如 Integer#even)。在这种情况下,您会得到这种行为:
puts Klass.new(4).even?.result # => true
根据您的具体情况,这可能就是您所追求的。或者,在您的情况下,可能是所有方法都委托对象来改变该对象,而不是 return 对象的新实例,在这种情况下不需要重新分配。
我不认为你可以使用 Ruby 现有的 Delegator 和 SimpleDelegator 构造,因为你可以将最终的 #result 调用链接到最后的唯一方法是如果每个委托调用 returns 类的实例。使用那些现有的构造将导致对 return 其正常 return 值的委托调用,然后链接将在那些 return 值 return 的任何对象上。例如,使用上面的代码,您会看到这种行为:
puts Klass.new(5).pred.pred.class # => "Klass"
使用 SimpleDelegator,您会看到这种行为
require 'delegate'
class Klass2 < SimpleDelegator
# Klass2 methods...
end
puts Klass2.new(5).pred.pred.class # => "Fixnum"
希望对您有所帮助。
我有一个 class Klass
,它的构造函数接受一个参数。我们应该能够调用此对象上未在 Klass
.
我们可以链接多个方法,但最后,我们必须使用 Klass#result
来获得如下结果:
Klass.new(5).pred.pred.result
这里的输出应该是3
。我尝试在 Klass
中使用 method_missing
并在对象的 class 中使用 send
,但如果没有我必须使用的 result
方法,那也可以工作。有人可以解释如何通过委派来完成吗?
你可以这样做:
class Klass
def initialize(number)
@number = number
end
def result
@number
end
def method_missing(method_name, *arguments, &block)
if @number.respond_to?(method_name)
@number = @number.method(method_name).call(*arguments, &block)
return self
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
# be sure to implement this...
end
end
puts Klass.new(5).pred.pred.result # => 3
但这是有问题的。在此特定示例中,由于#pred return 是一个新对象(它不会修改调用它的对象),我们必须将实例变量重新分配给结果。它适用于 return 新整数的 pred 和其他方法,但整数上的一些方法不 return 一个整数(例如 Integer#even)。在这种情况下,您会得到这种行为:
puts Klass.new(4).even?.result # => true
根据您的具体情况,这可能就是您所追求的。或者,在您的情况下,可能是所有方法都委托对象来改变该对象,而不是 return 对象的新实例,在这种情况下不需要重新分配。
我不认为你可以使用 Ruby 现有的 Delegator 和 SimpleDelegator 构造,因为你可以将最终的 #result 调用链接到最后的唯一方法是如果每个委托调用 returns 类的实例。使用那些现有的构造将导致对 return 其正常 return 值的委托调用,然后链接将在那些 return 值 return 的任何对象上。例如,使用上面的代码,您会看到这种行为:
puts Klass.new(5).pred.pred.class # => "Klass"
使用 SimpleDelegator,您会看到这种行为
require 'delegate'
class Klass2 < SimpleDelegator
# Klass2 methods...
end
puts Klass2.new(5).pred.pred.class # => "Fixnum"
希望对您有所帮助。