Ruby way第一章学习【Ruby的动态性】

Ruby是一种动态性相当高的语言,甚至在运行时,我们都可以对对象和类作修改。它可以在即有的静态代码的执行过程中构造生成和计算新的代码片段。

在运行时Coding
=====================================================
我们可以用eval来计算动态组成的表达式:
def calculate(op1, operator, op2)
string = op1.to_s + operator + op2.to_s
eval(string)
end

$alpha = 25
$beta = 12
puts calculate(2, "+", 2) # 4
puts calculate(5, "*", "$alpha") # 125
puts calculate("$beta", "**", 3) # 1728

甚至,我们可以动态定义新的方法或其他代码块:
puts "Method name: "
meth_name = gets.chomp
puts "Line of code: "
line = gets.chomp

string = %[def #{ meth_name} \n #{ line} \n end]
eval(string) # Define the method
eval(meth_name) # Call the method

在不同的平台下我们可能需要对代码所不同的处理,在C语言中,我们使用#ifdef指令来处理这样的问题,但,
那是在编译时作处理的,而Ruby中我们可以这样做:
if platform == Windows
action1
elsif platform == Linux
action2
else
default_action
end
不过上面的做法有些笨拙,因为一个程序中需要判断的地方太多了,从而导致这些判断会运行很多次,所以,
我们可以把上面的代码写成这样:
if platform == Windows
def my_action
action1
end
elsif platform == Linux
def my_action
action2
end
else
def my_action
default_action
end
end
这样,在以后的代码中,只管调用my_action就可以了,不需要再作类似的判断了。


Ruby中的反射
==============================================================
使用defined?关键字用来查看指定的变量名是否已经定义过。
if defined? some_var
print "some_var = #{ some_var} \n"
else
print "The variable some_var is not known.\n"
end

类似的,respond_to?用来查看对象是否存在指定的方法可供调用:
class Test
def test
end
end

a = Test.new
puts a.respond_to?(:test) #true
puts a.respond_to?(:test2) #false

Ruby可以调用对象的type(将过期)或class方法来获取该对象在运行时的类型,另外,可以用is_a?方法
(别名kind_of?)来判断指定对象是否是指定的类型,例如:
print "abc".type # Prints String
print 345.type # Prints Fixnum

rover = Dog.new
print rover.type # Prints Dog
if rover.is_a? Dog
print "Of course he is.\n"
end
if rover.kind_of? Dog
print "Yes, still a dog.\n"
end
if rover.is_a? Animal
print "Yes, he's an animal, too.\n"
end

还有一个方法更绝妙,就是methods方法
(还有些变种方法如private_methods, public_methods),
可以获取一个对象中拥有的所有的方法:
a.methods
a.private_methods

模块有个特别的方法constants用来获取它包含的所有的常量:
module Mod
HELLO = "hello"
WORLD = "world"
end

Mod.constants #HELLO,WORLD

模块有ancestors方法来获取一个模块的父模块:
module Mod
HELLO = "hello"
end

module Mod2
include Mod

WORLD = "world"
end

puts Mod.ancestors #Mod

而类有superclass方法来获取类实例的父类:
class T
end

class Q < T
end

puts Q.superclass #T


当发出一个方法的调用时,比如myobject.mymethod,Ruby查找该方法的顺序是:
1.查找myobject对象是否存在名为mymethod的singleton方法
2.查找myobject对象是否存在名为mymethod的实例方法
3.查找myobject对象的父类中是否存在名为mymethod的方法
这样一圈下来还是找不到的话,Ruby会在类中查找是否定义了method_missing这个方法,如果定义了的话,则会
把mymethod这个方法名(以symbol形式)及本来传给mymethod方法的所有参数作为参数传入method_missing:
class Test
def method_missing(a,p1,p2)
puts "method_missing has done!"
puts "#{ a}-#{ p1}-#{ p2}"
end
end

Test.new.test("aaa","bbb")






 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值