下面是学习中对ruby的一些常见的方法的总结:
1.
each方法经常与block一起使用,它的最大好处能够在某冲情况下取代for循环的功能。each方法会将调用它的对象中的所有元素依次赋给与each方法相关联的block的变量。
例如:
('a'..'e').each{ |char|
print char
}
输出结果是 abcde
在上面的例子中,range对象(‘a’..’e’)调用each方法,each方法将(‘a’..’e’)对象的每个值依次赋给block{|char| print char}中的char变量。
再来看下面这个例子:
file = File.open("c://sss.c") #打开名称为filename的文件,并将其内容写入到file中
file.each { |line|
puts line
}
file.close
输出结果:
this is line one
this is line two
this is line three
and so on……
2. capitalize方法
该方法是字符串类String的一个方法,对所有字符串都适用。它的作用是将调用该方法的字符串的首字母改为大写。举例如下:
s = “ruby”
s.capitalize
又如:
defsay_goodnight(name)
result = "Good night, #{name.capitalize}" #capitalize将参数name所代表的字符串的首字母改为大写
returnresult #其实这条语句是多余的,因为一个方法如果没有指定返回值,则默认返回最后一个表达式的值
end
puts say_goodnight("mum")
输出结果:
Good night,Mum
3.
调用times方法的一般是具体的数字(整数)对象,times会按照对象的要求来指定其后block的执行次数。该方法是整数支持的集中常用的迭代器之一。
例如:
5.time { print “*” }
输出结果:
*****
4.
upto()方法会有一个参数,它的参数的值将与调用它的对象的值构成一个range,然后再将该range内的值依次赋值给其后block中的变量。该方法是整数支持的集中常用的迭代器之一。
例如:
factorial = 1
1.upto(10) do |i| #
factorial*= i
end
puts factorial
执行结果为:
3628800
输出结果为:
345678
5.
inject方法可以遍历集合中的所有成员以累计出一个值,一般地,他可以求得集合中元素的和或积。例如:
[2,4,6,8].inject(0) { |sum,element| sum + element }
[2,4,6,8].inject(1) { |product,element| product * element }
上述两条语句展示了求集合中元素的和或积的方法。
inject方法的工作原理:
(1)
(2)
根据上述说明,可以很容易得出下面这些表达式的结果:
[2,4,6,8].inject(3) { |sum,element| sum + element }
[2,4,6,8].inject(2) { |product,element| product * element }
[2,4,6,8].inject { |sum,element| sum + element }
[2,4,6,8].inject { |product,element| product * element }
调用inject方法的是一个集合,这个集合可以是数值Array,同时它还可以是range,例如:
(2..5).inject(3) { |sum,element| sum + element }
(2..5).inject(2) { |product,element| product * element }
该集合也可以是数值Array的一部分,例如:
a = [2,4,6,8,10] .
a[0,2].inject(3) { |sum,element| sum + element }
输出结果:9
6.
abs方法的作用是取得调用它的数字对象的绝对值。例如:
a = -123
a.abs
(-123).abs
注意,abs(num)这种表达方式是错误的。
7.
downto()方法是upto()方法的逆方法。downto()方法有一个参数,调用它的对象的值它的参数的值将与构成一个range,然后再将该range内的值依次赋值给其后block中的变量。该方法是整数支持的集中常用的迭代器之一。
例如:
20.downto(15) { |i| print i, “
输出结果:20
8.
该方法的形式为:a.step(b,c) {block},它有两个参数,其中第一个参数b与调用该方法的数字对象b构成一个range。相当于是一个以a为首项,b为末项,c为公差的一个等差数列。step方法的作用就是将该等差数列的各项分别传入block中,即进行迭代。
例如:
10.step(20,2) {|i| print i, “,”}
输出结果:
10,12,14,16,18,20
注意,从数学的意义上讲,在setp方法中并不要求b = n*c成立(n为整数),只需要满足a < b成立即可。
例如:
12.step(26,5.1) {|i| print i, “,”}
输出结果:
12.0,17.1,22.2
#代码块的返回值可以被调用者使用。
b = [1, 2, 3, 4, 5].map do |entry| #将操作后的数据放入一个新的数组返回
entry * entry
end
print b.inspect
#执行结果为: [1, 4, 9, 16, 25]
当我们试着直接观察一个对象,就会出现一些像 #<anObject: 0x83678> 的东西.这只是个缺省的行为,我们可以自由地改变它.我们所要做的只是加一个名为 inspect 的方法.它会换一个更明了的描述对象的字符串,包括部分或全部的实变量。
ruby> class Fruit | def inspect | "a fruit of the " + @kind + " variety" | end | end nil ruby> f2 "a fruit of the banana variety"
一个相关的方法是to_s(转化为字符串),用在打印对象的时候.一般的,你可以认为 inspect 是一个编写或调试程序时用的工具,而 to_s 是一个美化程序输出的方法。eval.rb显示结果时总采用 inspect。 你可以用 p 方法简单的从程序里取得调试信息.
array = [2,4,6,8,10]
puts array
p array
print array
puts array输出的结果是:
2
4
6
8
10
p array的结果:[2, 4, 6, 8, 10]
ptint array的结果:12345 //末尾没有换行符
12.yield方法
在用yield时就像是在定义时包含它的块在遇到yield时执行和定义块名字相同的块一样!!!
在方法中可以使用yield来执行代码块的内容,就好像传入的代码块是这个方法的一部分一样。每当碰到一个yield调用,代码块的内容就会被执行一次。当代码块执行结束后,程序会回到yield的那一行继续向下执行。
def time
start = Time.now
yield
sleep(1)
puts Time.now
puts start
end
time { puts "code_here" }
time { puts "more_code_here1" }
time { puts "more_code_here2" }
#结果:
code_here
Sat Dec 31 11:51:46 +0800 2011
Sat Dec 31 11:51:45 +0800 2011
more_code_here1
Sat Dec 31 11:51:47 +0800 2011
Sat Dec 31 11:51:46 +0800 2011
more_code_here2
Sat Dec 31 11:51:48 +0800 2011
Sat Dec 31 11:51:47 +0800 2011
你可以使用yield操作传参数给一个代码块,并且从代码块取回返回值。
def fibonacii(max)
f1, f2 = 1, 1
while f1 <= max
yield f1
f1, f2 = f2, f1+f2
end
end
fibonacii(1000) { |f| print f, " " }
执行结果为:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
在这个例子中,yield接收一个参数,这个参数将会在执行的时候传递给指定的代码块。在代码块中,接收的参数使用两个竖线括起来放在代码块的头部。yield操作也可以有返回值,yield操作的返回值就是代码块中最后一个表达式的值。
13.Proc方法
结合代码块使用.有两种用法可以参考:主要是时实现把将要执行的代码片段存放在一起,不立即执行,等到我们要用的时候再执行。
①将一个代码块传递给最后一个参数以&开始的方法。
def meth1(p1, p2, &block)
puts block.inspect
puts block.call
end
meth1(1, 2) { "This is a block" }
②使用Proc.new方法,后边的参数为一个代码块:
block = Proc.new { "a block" } #代码不会立即执行
block.call #此时会执行Proc存放的代码
#结果: a block
用Proc来组织我们的代码
Proc是组织代码的好工具,比如现在我们要测试一下某些代码的执行花费时间,通过Proc可以很灵活地做到这一点:
def time(a_proc)
start = Time.now
a_proc.call
sleep(1)
puts Time.now - start
end
time(Proc.new { puts "code_here "})
time(Proc.new { puts "more_code_here "}) #此时的两个time是在call之后分别调用的,不是同时,是串行的!!
结果是:
code_here
1.0
more_code_here
1.0
14.call方法
Proc对象的使用方式和Method对象的一样,都是通过call方法来执行与之关联的代码逻辑,我们传给call方法的参数将会传给Proc对象包含的代码块,而代码块的执行结果将会通过call方法返回给我们。那么你可以proc方法来创建Proc对象,效果和通过Proc类的new方法来创建是一样的:
def call_test( b )
d = b+4;
ca = Proc.new{
|i| i +d
puts "call的方法 #{i+d}"}
ca.call(7)
end
hh(4)
#结果:call的方法 15
15.next方法
在一个代码块中执行next语句会导致代码块返回。返回值就是next语句后带的参数。如果next后没有参数,那么返回值为nil
def meth2
result = yield #执行meth2后的返回值赋值给result
"The block result is #{result}"
end
puts meth2 { next 9 }
pr = Proc.new { next 100 }
puts pr.call
pr = lambda { next }
puts pr.call
执行结果为:
The block result is 9
100
nil
15.alias 方法
这个方法是对一个函数名或者变量重新命名,当对变量重新命名之后就和旧的变量绑定在了一起,无论哪一个变量改变都会造成变量的改变。但是在重命名函数名(方法名的时候)有点不同,此后即使重新定义了原始方法,别名方法仍然保持着重定义前的老方法的特性。若改变了某方法的内容后,又想使用修改前的方法时,别名会很有用。
def meth
puts "I'm old!"
end
alias :new_meth :meth
def meth
puts "I'm new!!"
end
puts meth
puts new_meth
结果是:I'm new!!
I'm old!"
alias 与 alias_method的区别
1. alias是Ruby的一个关键字,而alias_method是Module类的一个方法
2. alias的参数就是方法本身(method identify),注意,不是字符串,也不是Symbol,alias_method的参数则是字符串或者symbol,并且使用逗号分隔。
3. alias_method可以重定义,而alias则不能
alias new_method_name old_method_name
alias_method :new_method_name, :old_method_name
alias_method 'new_method_name', 'old_method_name'
例如:
class B
def b
p "bbbbbb"
end
alias_method :cb,:b
end
d = B.new
d.cb
结果:bbbbb