如何创建一个方法来执行 Ruby 中先前给定的块?
How to create a method that executes a previously given block in Ruby?
我有一个 class 是为 subclassing 打造的。
class A
def initialize(name)
end
def some
# to define in subclass
end
end
# usage
p A.new('foo').some
#=> nil
在我的用例中,我不想创建子class,因为我只需要一个实例。因此,我将更改 initialize
方法以支持以下用法。
p A.new('foo') { 'YEAH' }.some
#=> YEAH
如何支持上述用法?
顺便说一句:我为 Ruby 1.8.7 项目找到了以下解决方案,但它们对我来说看起来很尴尬。
class A
def singleton_class
class << self; self; end
end
def initialize(name, &block)
@name = name
self.singleton_class.send(:define_method, :some) { block.call } if block_given?
end
def some
# to define in subclass
end
end
您可以稍后存储 block argument in an instance variable and call
它:
class A
def initialize(name, &block)
@name = name
@block = block
end
def some
@block.call
end
end
A.new('foo') { 'YEAH' }.some
#=> "YEAH"
您还可以将参数传递到块中:
class A
# ...
def some
@block.call(@name)
end
end
A.new('foo') { |s| s.upcase }.some
#=> "FOO"
或instance_exec
接收方上下文中的块:
class A
# ...
def some
instance_exec(&@block)
end
end
这允许你绕过封装:
A.new('foo') { @name.upcase }.some
#=> "FOO"
我有一个 class 是为 subclassing 打造的。
class A
def initialize(name)
end
def some
# to define in subclass
end
end
# usage
p A.new('foo').some
#=> nil
在我的用例中,我不想创建子class,因为我只需要一个实例。因此,我将更改 initialize
方法以支持以下用法。
p A.new('foo') { 'YEAH' }.some
#=> YEAH
如何支持上述用法?
顺便说一句:我为 Ruby 1.8.7 项目找到了以下解决方案,但它们对我来说看起来很尴尬。
class A
def singleton_class
class << self; self; end
end
def initialize(name, &block)
@name = name
self.singleton_class.send(:define_method, :some) { block.call } if block_given?
end
def some
# to define in subclass
end
end
您可以稍后存储 block argument in an instance variable and call
它:
class A
def initialize(name, &block)
@name = name
@block = block
end
def some
@block.call
end
end
A.new('foo') { 'YEAH' }.some
#=> "YEAH"
您还可以将参数传递到块中:
class A
# ...
def some
@block.call(@name)
end
end
A.new('foo') { |s| s.upcase }.some
#=> "FOO"
或instance_exec
接收方上下文中的块:
class A
# ...
def some
instance_exec(&@block)
end
end
这允许你绕过封装:
A.new('foo') { @name.upcase }.some
#=> "FOO"