在Ruby中的define_method内部使用yield [英] Using yield inside define_method in Ruby

查看:103
本文介绍了在Ruby中的define_method内部使用yield的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能使 yield 关键字在为define_method指定的块内起作用?简单的例子:

Is it possible to make yield keyword work inside a block given to define_method? Simple example:

class Test
  define_method :test do |&b|
    puts b    # => #<Proc:...>
    yield
  end
end

Test.new.test {
  puts "Hi!"
}

此代码在Ruby 1.8.7和1.9.0中均产生以下错误:

This code produces following error in both Ruby 1.8.7 and 1.9.0:

test.rb:4:在`test'中:没有给出块(LocalJumpError) 来自test.rb:8

test.rb:4:in `test': no block given (LocalJumpError) from test.rb:8

奇怪的是 b 块变量!= nil,但block_given?返回false. Ruby的故意行为是不识别 Proc 对象的块吗?

The strange thing is the b block variable != nil but block_given? returns false. Is it intentional Ruby behaviour not to recognize blocks by Proc objects?

关于 Beerlington 的回答:b.call()不是我想要的.块变量仅用于指示实际上已给出了块,而在define_method内部未检测到该变量.

Regards to Beerlington's answer: b.call() is is not what I am looking for. Block variable was used only to indicate that block is actually given, and is not detected inside define_method.

我愿意为Ruby中定义新类的方式写一些扩展,因此任何代码在使用扩展名时都应该接受可以用纯Ruby编写的代码.

I am willing to write some extension to the way how new classes are defined in Ruby, thus any code You can write in pure Ruby should be accepted when I use my extension.

因此,不能考虑类似的语​​义,因为这迫使我的库的用户仅使用一种适当的方式来传递块.这违反了TIMTOWTDI规则,并且没有使我的库透明.

So similar semantics cannot be taken into consideration, because this forces users of my library to use only one proper way to pass a block. This breaks the TIMTOWTDI rule, and does not make my library transparent.

下面的代码可以简化为上面的代码,因为my_def使用define_method:

Code below can be simplified to code above since my_def uses define_method:

require 'my_library'

class Test
  # client can write 'my_def' instead of 'def' since
  # my_library extends Class class
  my_def :test, "some parameter" do
    yield        # oh no, error :(
  end
end

Test.new.test {
  puts "Hi!"
}

推荐答案

我认为这是您要寻找的:

I think this is what you're looking for:

class Test
  define_method :test do |&b|
    b.call
  end
end

Test.new.test {
  puts "Hi!"
}

更多信息,请参见 http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/

这篇关于在Ruby中的define_method内部使用yield的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆