首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ruby中使方法动态化

在ruby中使方法动态化
EN

Stack Overflow用户
提问于 2018-09-07 17:29:05
回答 2查看 61关注 0票数 0

按如下方式定义一个类。我想动态调用one_method。默认情况下,wow.one_method调用第一个one_method。如果我想改变方法的行为,只需调用redefine即可。

我可以将该方法实现为函数类型属性,但这不是我想要的。

如果我直接使用下面的代码,它将报告错误。你能稍微修改一下吗?

代码语言:javascript
复制
class Wow

    def one_method
        puts "hello Ruby"
    end

    def redefine(what="none")
        define_method :one_method do 
        puts what
        end
    end
end

wow = Wow.new
wow.redefine("Whatever I want.")
EN

回答 2

Stack Overflow用户

发布于 2018-09-07 17:44:25

您可以通过class_evalinstance_eval实现这一点

代码语言:javascript
复制
class Wow

  def one_method
    puts "hello Ruby"
  end

  def redefine(what="none")
    self.class.class_eval do
      define_method :one_method do 
        puts what
      end
    end
  end
end

wow = Wow.new
wow.one_method #=> hello Ruby

wow.redefine("Whatever I want.")
wow.one_method #=> Whatever I want.

原因是define_method在接收器上定义了实例方法,并且是一个类的实例方法,所以你必须在你想要重新定义方法的对象的eigen类上调用它。

票数 1
EN

Stack Overflow用户

发布于 2018-09-07 18:26:09

我建议以一种更规范的方式实现您的目标,只需在实例本身上重新定义方法:

代码语言:javascript
复制
class Wow
  def one
    :one
  end
end

w = Wow.new
w.one
#=> :one

def w.one
  :two
end

w.one
#=> :two

缺点是:

  • 您的方法查找表缓存将被丢弃
  • 代码变得越来越晦涩难懂且难以调试

替代方案:

我不知道您的真正问题,但对于您的特定问题,最好是将您的one_method方法参数化,以便接收puts的参数。此外,您可以传递一个块,因此您将获得对行为的更细粒度的控制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52219538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档