ruby send respond_to
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:
- Unlike send(), public_send() calls public methods only.
- Similar to send(), we also have an instance method __send()__ of the BasicObject class.
如同其他的OO语言一样,在ruby中,通过给对象发送消息,来完成对象的功能,比如 str.upcase ,就是给str发送upcase的消息,点操作符(.),就是用来给对象发送消息的,str接受到消息,然后执行与消息对应的功能。
但是,某些时候,我们并不知道对象能响应哪些消息,比如下面的代码就会产生错误:
- > obj = Object.new
- > obj.talk
- undefined method 'talk' for #<Object:0x12345678> (NoMethodError)
因为obj对象没法响应talk这个消息,如果使用 respond_to? 这个方法,就可以实现判断对象能否响应给定的消息了:
- obj = Object.new
- if obj.respond_to?("talk")
- obj.talk
- else
- puts "Sorry, object can't talk!"
- end
这样即使obj不能响应talk,也不会使代码产生错误退出,我们也可以应用 respond_to? 方法,根据对象的属性,在程序运行时灵活的控制。
与 respond_to? 相对应,send 方法和点操作符一样,用来给对象发送消息,比如文章开始的 str.upcase ,用 send 可以写成 str.send("upcase"),它们实现的功能是完全相同的,那么为什么还要用send呢?
这是因为,send 发送的消息,在程序运行时是可变的,我们可以根据不同的输入,动态的向对象发送不同的消息。
比如一个图书管理系统,每本书都有诸如作者、出版社、日期、价钱这些,我们要根据用户的输入查询某本书的属性,如果不用send,我们要对程序的输入做一个一个的测试:
- print "Search for: "
- request = gets.chomp
- if request == "writer"
- puts book.writer
- elsif request == "press"
- puts book.press
- elseif request == "date"
- puts book.date
- ......
如果用send方法的话,就简单多了:
- request = gets.chomp
- if book.respond_to?(request)
- puts book.send(request)
- else
- puts "Input error"
- end
这样不用在逐个对用户的输入进行测试,只要查询对象能否相应这个消息,再用send将输入直接发送给对象即可。
通过 respond_to? 和 send 这两个方法,我们可以构造更灵活和稳定的程序。
ruby send respond_to的更多相关文章
- ruby 模块 respond_to
def hi puts 'hi friend' end module Amodule def self.hello puts 'hello friend' end end def rsp(txt) p ...
- Ruby 一些经常使用的细节
1.try 永远不会抛出异常 在 没有的时候 返回 nil province_id = Province.find_by_name(prov).try(:id) 2.find(:first, :con ...
- metasploit--exploit模块信息
Name Disclosure Date Rank Description ---- ...
- 使用Bootstrap Bar来增加Onboarding Progress Bar功能。
git初始代码https://github.com/chentianwei411/at-mentions-with-action-text 首先,开分支onboardingbar. 然后, rails ...
- Kali linux 2016.2(Rolling)中的Exploits模块详解
简单来将,这个Exploits模块,就是针对不同的已知漏洞的利用程序. root@kali:~# msfconsole Unable to handle kernel NULL pointer der ...
- 【ruby】ruby基础知识
Install Ruby(安装) For windows you can download Ruby from http://rubyforge.org/frs/?group_id=167 for L ...
- Ruby基础类型,动态特性,代码块
#Ruby内置基础数据类型 NilClass,TureClass,FalseClass,Time,Date,String,Range,Struct,Array,Hash #Numerice 1.分为I ...
- Ruby学习之动态调用
作为一个动态语言,对象中的方法不会像静态语言一样需要验证确实存在,动态语言的对象之间一直保持着交谈,如果你调用一个不曾定义过的方法,程序也不会马上就报错而无法运行,只有当运行到你调用这个方法时,解释器 ...
- ruby技巧001:求md5散列
ruby核心库中未包含md5之类的功能,不过在其标准库digest中可以方便的使用该功能: = Digest (from ruby core) ---------------------------- ...
随机推荐
- Android开发之5大布局方式详解
Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...
- .NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序
.NET 跨平台RPC框架DotNettyRPC DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...
- go语言学习 ---iota
iota iota,特殊常量,可以认为是一个可以被编译器修改的常量. iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota ...
- ADF_ADF基本概要(汇总)
20150601 Created By BaoXinjian
- linux page buffer cache深入理解
Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO(Free Output).例如: FO[2][1] = ...
- C# ASE加密解密
项目中比较常用的加密手段 /// <summary> /// ASE_128_ECB_无填充_64Base_加密函数 /// </summary> /// <param ...
- ubuntu16.4安装中文输入法
ibus输入法 Chinese语言包安装 首先需要给Ubuntu16.04安装Chinese语言包支持. 如上图点击其中的Install/Remove Languages…,这个对话框是通过syst ...
- 清除sqlserver日志方法(不适合always on)
清除sqlserver日志方法 --查看数据库的recovery_model_desc类型 SELECT NAME, recovery_model_desc FROM sys.databases -- ...
- sqlite数据库部署到服务器上的问题
试了一天...本地测试是好的(WIN10 64位+VS2015),部署到服务器上(WIN2008 32位+IIS6) 总是不行..按网上说了什么不要BUNDLE的,加入X86X64目录再放那个SQLi ...
- Python 计算两个IP段之间的有效IP地址
Can anyone think of an algorithm to put all of the addresses between two others and put them in a li ...