Programming Ruby 读书笔记(五)

来源:互联网 发布:windows telent 编辑:程序博客网 时间:2024/05/17 23:28

关于Ruby的方法调用

ruby中使用def来定义一个方法。方法名必须以一个小写字母开头(大写会被误认为是常量)。

表示查询的方法名通常以?结尾;危险的或者会修改接受者对象的方法,可以用!结尾。

ruby的方法支持可变长度的参数列表。

def varargs(arg, *rest)
  puts 
"Got #{arg} and #{rest.join(', ')}"
end

varargs(
"one")
varargs(
"one", "two")
varargs(
"one", "two", "three")

输出

Got one and
Got one and two
Got one and two, three

方法和Block

def take_block(p1)
  
if block_given?
    yield(p1)
  
else
    p1
  end
end
puts take_block(
"no block")
puts take_block(
"no block") { |s| s.sub(/no /, '') }

输出

no block
block

如果方法定义的最后一个参数前缀为&,则所关联的block会被转换为一个Proc对象,然后赋值给这个参数。

class TaxCalulator
  
  def initialize(name
, &block)
    
@name, @block = name, block
  end
  
  def get_tax(amount)
    
"#@name on #{amount} = #{ @block.call(amount) }"
  end
  
end

tc 
= TaxCalulator.new("Sales tax") { |amt| amt * 0.075 }
puts tc
.get_tax(100)
puts tc
.get_tax(250)

输出

Sales tax on 100 = 7.5
Sales tax on 250 = 18.75

ruby的方法支持返回多值(这时return不可省)

def method_two
  
return "a", "b"
end

puts method_two

输出

a
b

在方法调用中的数组展开(数组参数前加一个星号)

def five(a, b, c, d, e)
  
"I was passed #{a} #{b} #{c} #{d} #{e}"
end
puts five(
1, 2, 3, 4, 5)
puts five(
1, 2, 3, *['a', 'b'])
puts five(
*(10..14).to_a)

输出:

I was passed 1 2 3 4 5
I was passed 1 2 3 a b
I was passed 10 11 12 13 14

我们可以使用下面的方法让block更加动态

print "(t)imes or (P)lus: "
times = gets
print "number: "
number 
= Integer(gets)
if times =~ /^t/
  puts ((
1..10).collect { |n| n*number }.join(""))
else
  puts ((
1..10).collect { |n| n+number }.join(""))
end

输出

(t)imes or (P)lus: t
number: 2
2, 4, 6, 8, 10, 12, 14, 16, 18, 20

抽出block后代码

print "(t)imes or (P)lus: "
times = gets
print "number: "
number 
= Integer(gets)
if times =~ /^t/
  calc 
= lambda{ |n| n*number }
else
  calc 
= lambda{ |n| n+number }
end

puts ((
1..10).collect(&calc).join(""))

输出

(t)imes or (P)lus: t
number: 2
2, 4, 6, 8, 10, 12, 14, 16, 18, 20

以上的代码中,注意&符号的使用。如果在方法的最后一个参数前面加&,Ruby会认为他是一个Proc对象。他会将其从参数列表中删除,并将Proc对象转换成一个block,然后关联到该方法。