Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建一个在Ruby中执行先前给定块的方法?_Ruby_Metaprogramming_Eigenclass - Fatal编程技术网

如何创建一个在Ruby中执行先前给定块的方法?

如何创建一个在Ruby中执行先前给定块的方法?,ruby,metaprogramming,eigenclass,Ruby,Metaprogramming,Eigenclass,我有一个为子类化而构建的类 class A def initialize(name) end def some # to define in subclass end end # usage p A.new('foo').some #=> nil 在我的用例中,我不想创建子类,因为我只需要一个实例。因此,我将更改initialize方法以支持以下用法 p A.new('foo') { 'YEAH' }.some #=> YEAH 我如何支持上述用法

我有一个为子类化而构建的类

class A
  def initialize(name)
  end

  def some
    # to define in subclass
  end
end

# usage
p A.new('foo').some
#=> nil
在我的用例中,我不想创建子类,因为我只需要一个实例。因此,我将更改
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
A类
def singleton_类
类您可以将

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"
或接收器上下文中的块:

class A
  # ...

  def some
    instance_exec(&@block)
  end
end
它允许您绕过封装:

A.new('foo') { @name.upcase }.some
#=> "FOO"
您可以将存储在实例变量中,稍后再使用:

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"
或接收器上下文中的块:

class A
  # ...

  def some
    instance_exec(&@block)
  end
end
它允许您绕过封装:

A.new('foo') { @name.upcase }.some
#=> "FOO"