动态替换Ruby中对象的方法实现
发布时间:2020-12-17 04:34:54 所属栏目:百科 来源:网络整理
导读:我想用一个用户指定的块替换对象的方法的实现.在 JavaScript中,这很容易实现: function Foo() { this.bar = function(x) { console.log(x) }}foo = new Foo()foo.bar("baz")foo.bar = function(x) { console.error(x) }foo.bar("baz") 在C#中它也很容易 cla
我想用一个用户指定的块替换对象的方法的实现.在
JavaScript中,这很容易实现:
function Foo() { this.bar = function(x) { console.log(x) } } foo = new Foo() foo.bar("baz") foo.bar = function(x) { console.error(x) } foo.bar("baz") 在C#中它也很容易 class Foo { public Action<string> Bar { get; set; } public Foo() { Bar = x => Console.WriteLine(x); } } var foo = Foo.new(); foo.Bar("baz"); foo.Bar = x => Console.Error.WriteLine(x); foo.Bar("baz"); 但是我怎么能在Ruby中做同样的事情呢?我有一个解决方案,将lambda存储在一个实例变量中,该方法调用lambda,但我真的不喜欢开销和语法 class Foo def initialize @bar = lambda {|x| puts x} end def bar x @bar.call x end def bar= blk @bar = blk end end foo = Foo.new foo.bar "baz" foo.bar= lambda {|x| puts "*" + x.to_s} foo.bar "baz" 我想要这样的语法: foo.bar do |x| puts "*" + x.to_s end foo.bar "baz" 我想出了以下代码 class Foo def bar x = nil,&blk if (block_given?) @bar = blk elsif (@bar.nil?) puts x else @bar.call x end end end 但是这对于多个参数来说有点难看,但仍然感觉不对.我也可以定义一个set_bar方法,但我不喜欢这样:). class Foo def bar x if (@bar.nil?) puts x else @bar.call x end end def set_bar &blk @bar = blk end end 所以问题是:有没有更好的方法来做到这一点,如果没有,你更喜欢什么方式 编辑: prefix = "*" def foo.bar x puts prefix + x.to_s end 不起作用.我想我必须坚持使用lambda才能工作? 解决方法
使用def:
foo = Foo.new foo.bar "baz" def foo.bar x puts "*" + x.to_s end foo.bar "baz" 是的,那么简单 编辑:为了不松开范围,您可以使用define_singleton_method(如@freemanoid答案): prefix = "*" foo.define_singleton_method(:bar) do |x| puts prefix + x.to_s end foo.bar 'baz' (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |