• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >ruby > Ruby元编程之梦中情人method_missing方法详解

Ruby元编程之梦中情人method_missing方法详解

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了ruby method missing,ruby,ruby rose,ruby什么意思,max and ruby等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

我最近读了些文章(比如这篇),宣传在 Ruby 里使用 method_missing 的。

很多人都与 method_missing 干柴烈火,但在并没有小心处理彼此之间的关系。所以,我想来探讨一下这个问题:

** 我该怎么用 method_missing **

什么时候该抵挡 method_missing 的诱惑

首先,永远不要在还没花时间考虑你用得够不够好之前,就向 method_missing 的魅力屈服。你知道,在日常生活中,很少会让你以为的那样亟需 method_missing:

日常:方法代理

案例:我需要让这个类能够使用另一个类的方法

这是我所见过最普遍的使用 method_missing 的情况。这在 gems 与 Rails 插件里头尤其流行。它的模型类似这样:
class A
  def hi
    puts "Hi from #{self.class}"
  end
end

class B
  def initialize
    @b = A.new
  end

  def method_missing(method_name, *args, &block)
    @b.send(method_name, *args, &block)
  end
end

A.new.hi #=> Hi from A
B.new.hi #=> Hi from A
</div>
如此,B 就拥有了 A 的所有实例方法。但是让我们想想,在调用 @b.hi 的时候都发生了什么。你的 ruby 环境沿着继承链一路找 hi 这个方法,到最后,恰恰在丢出个 NoMethodError 前,它调了 method_missing 这个方法。

在上例中,情况并不坏,毕竟这里就两个微不足道的类需要查。但通常,我们是在 Rails 或者其他一些框架的上下文中编程。而你的 Rails 模型继承自 ActiveRecord,而它又集成自其他一大坨的类,于是现在你就有了一坨高高的堆栈要爬⋯⋯ 在你每次调用 @b.hi 的时候!

你的好基友:define_method

估计现在你在抱怨,“但是史蒂夫,我需要 method_missing” 我告诉你,别忘了其实除了情妇之外,你还有个忠诚的好基友,叫做 define_method。

它允许你动态地定义一个方法(顾名思义)。它的伟大之处在于,在它执行过之后(通常在你的类们加载之后),这些方法就存在你的类中了,简单直接。在你创建这些方法的时候,也没有什么继承链需要爬。

define_method 很有爱很可靠,并且能够满足你的日常生活。不信我?接着看⋯⋯
class B
  define_method(:hi) do
    @b.hi
  end
end
</div>
“可是我有一大坨方法要定义!” 你抱怨

“没问题!” 我卖萌眨眼
class B
  [:hi, :bye, :achoo, :gesundheit].each do |name|
    define_method(name) do
      @b.send(name)
    end
  end
end
</div>
可是我懒得把它们一个个写出来!

你有点难搞哦
class A
  # ... lots of methods in here
end
class B
  A.instance_methods.each do |name|
    define_method(name) do
      @b.send(name)
    end
  end
end
</div>
那假如我要定义的方法跟原本的有那么一些些不一样呢?

容易
class A
  def hi
    puts "Hi."
  end
end

class B
  A.instance_methods.each do |name|
    define_method("what_is_#{name}") do
      if @b.respond_to?(name)
        @b.send(name)
      else
        false
      end
    end
  end
end

B.new.what_is_hi #=> "Hi."
B.new.what_is_wtf #=> false
</div>
呃,代码看起来不优雅啊

那就没办法了,凑合得了。如果你想要代码更易读,可以看看我们的ruby delegation library 和 Rails ActiveRecord delegation。

好,我们总结一下,看看 define_method 的真正威力。

修改自 ruby-doc.org 上的 例子
class A
  def fred
    puts "In Fred"
  end
  def create_method(name, &block)
    self.class.send(:define_method, name, &block)
  end
  define_method(:wilma) { puts "Charge it!" }
end
class B < A
  define_method(:barney, instance_method(:fred))
end

a = B.new
a.barney                                #=> In Fred
a.wilma                                 #=> Charge it!
a.create_method(:betty) { p self.to_s }
a.betty                                 #=> B
</div>
什么时候用 method_missing?

现在你估计在想,总有该用它的时候吧,不然还要它干嘛?没错。

动态命名的方法(又名,元方法)

案例:我要依据某种模式提供一组方法。这些方法做的事情顾名思义。我可能从来没有调用过这些可能的方法,但是等我要用的时候,它们必须可用。

现在才是人话!这其实正是 ActiveRecord 所采用的方式,为你提供那些基于属性的动态构建的查找方法,比如 find_by_login_and_email(user_login, user_email)。

def method_missing(method_id, *arguments, &block)
  if match = DynamicFinderMatch.match(method_id)
    attribute_names = match.attribute_names
    super unless all_attributes_exists?(attribute_names)
    if match.finder?
      # ...you get the point
    end # my OCD makes me unable to omit this
    # ...
  else
    super # this is important, I'll tell you why in a second<

您可能想查找下面的文章:

  • Ruby简明教程之方法(Method)介绍
  • ruby元编程之method_missing的一个使用细节
  • Ruby元编程之梦中情人method_missing方法详解

相关文章

  • 举例讲解Ruby中迭代器Iterator的用法
  • Ruby设计模式编程之适配器模式实战攻略
  • ruby中执行周期性任务(定时任务)的3种方法
  • Ruby元编程的一些值得注意的地方
  • Ruby中的block、proc、lambda区别总结
  • ruby 学习笔记(1) 初识语法
  • Rails link_to 详解
  • 关于Ruby on Rails视图编写的一些建议
  • Ruby中使用mechanize批量下载校内网相册照片
  • mac os gem安装json出现error failed的解决办法

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Ruby 取得指定月日期数的方法
    • 使用Ruby实现FTP密码破解
    • 在Ruby on Rails中优化ActiveRecord的方法
    • Ruby设计模式编程中使用Builder建造者模式的实例
    • Rails Routes中new、collection、member的区别浅析
    • Ruby 魔法 学习笔记之一
    • CentOS 7下配置Ruby语言开发环境的方法教程
    • 使用Ruby来处理JSON的简单教程
    • Ruby语言中的String深入理解
    • rudy 继承 概念

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有