http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

http://galeki.is-programmer.com/posts/183.html

1.3.2 send 

send( ) is an instance method of the Object class. The first argument to send( ) is the message that you're sending to the object - that is, the name of a method. You can use a string or a symbol, but symbols are preferred. Any remaining arguments are simply passed on to the method.

class Rubyist
def welcome(*args)
"Welcome " + args.join(' ')
end
end
obj = Rubyist.new
puts(obj.send(:welcome, "famous", "Rubyists")) # => Welcome famous Rubyists

With send( ), the name of the method that you want to call becomes just a regular argument. You can wait literally until the very last moment to decide which method to call, while the code is running.

class Rubyist
end rubyist = Rubyist.new
if rubyist.respond_to?(:also_railist)
puts rubyist.send(:also_railist)
else
puts "No such information available"
end

In the code above, if the rubyist object knows what to do with :also_railist, you hand the rubyist the message and let it do its thing.

You can call any method with send( ), including private methods.

class Rubyist
private
def say_hello(name)
"#{name} rocks!!"
end
end
obj = Rubyist.new
puts obj.send( :say_hello, 'Matz')

Note:

  1. Unlike send()public_send() calls public methods only.
  2. Similar to send(), we also have an instance method __send()__ of the BasicObject class.

如同其他的OO语言一样,在ruby中,通过给对象发送消息,来完成对象的功能,比如 str.upcase ,就是给str发送upcase的消息,点操作符(.),就是用来给对象发送消息的,str接受到消息,然后执行与消息对应的功能。

但是,某些时候,我们并不知道对象能响应哪些消息,比如下面的代码就会产生错误:

  1. > obj = Object.new
  2. > obj.talk
  3.  
  4. undefined method 'talk' for #<Object:0x12345678> (NoMethodError)

因为obj对象没法响应talk这个消息,如果使用 respond_to? 这个方法,就可以实现判断对象能否响应给定的消息了:

  1. obj = Object.new
  2. if obj.respond_to?("talk")
  3.    obj.talk
  4. else
  5.    puts "Sorry, object can't talk!"
  6. end

这样即使obj不能响应talk,也不会使代码产生错误退出,我们也可以应用 respond_to? 方法,根据对象的属性,在程序运行时灵活的控制。

与 respond_to? 相对应,send 方法和点操作符一样,用来给对象发送消息,比如文章开始的 str.upcase ,用 send 可以写成 str.send("upcase"),它们实现的功能是完全相同的,那么为什么还要用send呢?

这是因为,send 发送的消息,在程序运行时是可变的,我们可以根据不同的输入,动态的向对象发送不同的消息。

比如一个图书管理系统,每本书都有诸如作者、出版社、日期、价钱这些,我们要根据用户的输入查询某本书的属性,如果不用send,我们要对程序的输入做一个一个的测试:

  1. print "Search for: "
  2. request = gets.chomp
  3.  
  4. if request == "writer"
  5.   puts book.writer
  6. elsif request == "press"
  7.   puts book.press
  8. elseif request == "date"
  9.   puts book.date
  10. ......

如果用send方法的话,就简单多了:

  1. request = gets.chomp
  2.  
  3. if book.respond_to?(request)
  4.   puts book.send(request)
  5. else
  6.   puts "Input error"
  7. end

这样不用在逐个对用户的输入进行测试,只要查询对象能否相应这个消息,再用send将输入直接发送给对象即可。

通过 respond_to? 和 send 这两个方法,我们可以构造更灵活和稳定的程序。

ruby send respond_to的更多相关文章

  1. ruby 模块 respond_to

    def hi puts 'hi friend' end module Amodule def self.hello puts 'hello friend' end end def rsp(txt) p ...

  2. Ruby 一些经常使用的细节

    1.try 永远不会抛出异常 在 没有的时候 返回 nil province_id = Province.find_by_name(prov).try(:id) 2.find(:first, :con ...

  3. metasploit--exploit模块信息

    Name                                             Disclosure Date  Rank    Description ----           ...

  4. 使用Bootstrap Bar来增加Onboarding Progress Bar功能。

    git初始代码https://github.com/chentianwei411/at-mentions-with-action-text 首先,开分支onboardingbar. 然后, rails ...

  5. Kali linux 2016.2(Rolling)中的Exploits模块详解

    简单来将,这个Exploits模块,就是针对不同的已知漏洞的利用程序. root@kali:~# msfconsole Unable to handle kernel NULL pointer der ...

  6. 【ruby】ruby基础知识

    Install Ruby(安装) For windows you can download Ruby from http://rubyforge.org/frs/?group_id=167 for L ...

  7. Ruby基础类型,动态特性,代码块

    #Ruby内置基础数据类型 NilClass,TureClass,FalseClass,Time,Date,String,Range,Struct,Array,Hash #Numerice 1.分为I ...

  8. Ruby学习之动态调用

    作为一个动态语言,对象中的方法不会像静态语言一样需要验证确实存在,动态语言的对象之间一直保持着交谈,如果你调用一个不曾定义过的方法,程序也不会马上就报错而无法运行,只有当运行到你调用这个方法时,解释器 ...

  9. ruby技巧001:求md5散列

    ruby核心库中未包含md5之类的功能,不过在其标准库digest中可以方便的使用该功能: = Digest (from ruby core) ---------------------------- ...

随机推荐

  1. 【转】一个对 Dijkstra 的采访视频

    一个对 Dijkstra 的采访视频 (也可以访问 YouTube 或者从源地址下载 MPEG1,300M) 之前在微博上推荐了一个对 Dijkstra 的采访视频,看了两遍之后觉得实在很好,所以再正 ...

  2. pandas 按照某一列进行排序

    pandas排序的方法有很多,sort_values表示根据某一列排序 pd.sort_values("xxx",inplace=True) 表示pd按照xxx这个字段排序,inp ...

  3. php DES加密或者解密

    function pkcs5_pad ($text, $blocksize) { //加密时的字节填充,保持和java 一致 $pad = $blocksize - (strlen($text) % ...

  4. python标准库介绍——2 os.path模块详解

    == os.path 模块 == ``os.path`` 模块包含了各种处理长文件名(路径名)的函数. 先导入 (import) ``os`` 模块, 然后就可以以 ``os.path`` 访问该模块 ...

  5. Oracle学习笔记之四,SQL语言入门

    1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...

  6. RhinoMock学习-Stub方法

    // Arrange var stub = MockRepository.GenerateStub<IDemo>(); stub.Stub(x => x.StringArgStrin ...

  7. 【Android】19.2 ShareActionProvider类—帮你把信息分享出去

    分类:C#.Android.VS2015: 创建日期:2016-03-06 一.简介 共享操作提供程序类(ShareActionProvider)简化了你希望与其他人(或者其他应用程序)共享或分享出来 ...

  8. HDU 4670 Cube number on a tree ( 树的点分治 )

    题意 : 给你一棵树 . 树的每一个结点都有一个权值 . 问你有多少条路径权值的乘积是一个全然立方数 . 题目中给了你 K 个素数 ( K <= 30 ) , 全部权值都能分解成这k个素数 思路 ...

  9. Hadoop权威指南学习笔记一

    Hadoop简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出.一起学习一起进步. 转载请注明:http://blog.csdn.net/ ...

  10. VS2012, opencv2.4.4环境搭建

    2.1 环境准备 安装 Visual Studio 2012 下载 opencv 最新版本( 目前是2.4.6, 下载链接 ) 2.2 安装 opencv 2.2.1. 双击下载的 OpenCV-2. ...