加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

我可以动态定义一个带块的Ruby方法吗?

发布时间:2020-12-16 19:09:36 所属栏目:百科 来源:网络整理
导读:我知道我可以使用define_method在类上动态定义方法,并且我使用块的arity指定此方法所使用的参数. 我想动态定义一个接受可选参数和块的方法.在Ruby 1.9中,这很容易,因为现在允许将块传递给块. 不幸的是,Ruby 1.8不允许这样做,所以以下内容不起作用: #Ruby 1.
我知道我可以使用define_method在类上动态定义方法,并且我使用块的arity指定此方法所使用的参数.

我想动态定义一个接受可选参数和块的方法.在Ruby 1.9中,这很容易,因为现在允许将块传递给块.

不幸的是,Ruby 1.8不允许这样做,所以以下内容不起作用:

#Ruby 1.8
class X
  define_method :foo do |bar,&baz|
    puts bar
    baz.call if block_given?
  end
end

x = X.new
x.foo("foo") { puts "called!"} #=> LocalJumpError: no block given

用yield替换显式的block.call也不能解决问题.
遗憾的是,升级到Ruby 1.9对我来说不是一个选择.这是一个棘手的问题,还是有办法绕过它?

解决方法

这适用于Ruby 1.8.7,但不适用于1.8.6:
class X
  define_method(:foo) do |bar,&baz|
    puts bar
    baz.call if baz
  end
end

测试用:

X.new.foo("No block")
X.new.foo("With block") { puts "  In the block!"}
p = proc {puts "  In the proc!"}
X.new.foo("With proc",&p)

得到:

No block
With block
  In the block!
With proc
  In the proc!

(1.8.6会出现语法错误,意外的tAMPER,期待’|’.)

如果你想要可选参数以及阻止,你可以尝试这样的事情:

class X
  define_method(:foo) do |*args,&baz|
    if args[0]
      bar = args[0]
    else
      bar = "default"
    end
    puts bar
    baz.call if baz
  end
end

测试:

X.new.foo
X.new.foo { puts "  No arg but block"}

得到:

default
default
  No arg but block

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读