8.1 方法定义
def methodName(首字母小写/下划线)。若使用了大写,在调用的时候,ruby会认为这个一个常量,而不是一个方法,就会出现错误。
方法后可以跟? ! =。如果方法返回是boolean,则代?
1.even? #=>false 2.even? #=>true 1.instance_of(Fixnum) #=>true
如果方法会修改接收者(object.method,那object就是这个方法的接受者),或者方法的操作有危险性,使用!。比如String有chop与chop!,前者返回一个修改COPY,后者直接修改当前string。
如果以=结尾(suffix)用以表示给=左边赋值。
入参
入参可设默认值,使用arg=expression,当调用者没有显示的设时使用该默认值,expression可以引用前面的入参。
#示例演示第二个参数引用第一个参数 #string * 整数,表示string复制整数个。 def surround(word, pad_width=word.length/2) "[" * pad_width + word + "]" * pad_width end surround("elephant") #=>"[[[[elephant]]]]" surround("fox") # => "[fox]" surround("fox", 10) # => "[[[[[[[[[[fox]]]]]]]]]]返回值
ruby返回方法第后一行的执行结果,或者显示的return。
变长的参数列表
变化参数使用*作前缀。不要求放在最后一个位置。变长参数只允许有一个。
#分配给变长参数的是一个数组 def varargs(arg1, *rest) "arg1=#{arg1}". rest=#{rest.inspect}" end varargs("one") # => arg1=one. rest=[] varargs("one", "two") # => arg1=one. rest=["two"] varargs "one", "two", "three" # => arg1=one. rest=["two", "three"]
变长参数常用来表示参数可输可不输。在调用父方法时,对这种参数的传递需要注意。
#调用父方法传变长参数,使用super就可以,表示有就传,没有就不传 class Child < Parent def do_something(*not_used) #our processing super end end #对于这种情况,*not_used直接使用*就可以了。
变长参数可放在任意参数的位置:
def split_apart(first, *splat, last) puts "First: #{first.inspect}, splat: #{splat.inspect}, " + "last: #{last.inspect}" end split_apart(1,2) split_apart(1,2,3) split_apart(1,2,3,4) produces: First: 1, splat: [], last: 2 First: 1, splat: [2], last: 3 First: 1, splat: [2, 3], last: 4
上面还可以直接写成:
#直接使用* def split_apart(first, *, last)
变长参数:不允许多个,不可以使用默认值。
方法,块
方法内使用yield(args)调用传入的块。
如果最后一个参数使用&(ampersand)标注,则表示这个参数接收块,并会被转换为一个Proc对象,
class TaxCalculator def initialize(name, &block) @name, @block = name, block #这种赋值方式,有意思 end def get_tax(amount) puts "#@name on #{amount} = #{ @block.call(amount)}" # call中amount入参 end end tc = TaxCalculator.new("Sales tax") {|amt| amt * 0.075 } tc.get_tax(100) # => "Sales tax on 100 = 7.5" tc.get_tax(250) # => "Sales tax on 250 = 18.75"
8.2 Calling a Method(方法调用)
调用一个方法,可指定也可以不指定接收者(object.method=object就是接收者)。
connection.download_mp3("jitterbug") {|p| show_process(p)}
#connection是接收者。
当方法被调用时,Ruby首先将self设给接收者,然后调用接收者的该方法。
如果方法是类方法或者模块方法,则接收者就是类名或模块名。
Passing Parameters to a Method
Method Return Values
每个方法都有返回值,
#这个示例倒可以看看case when else end 语法 def meth_two(arg) case when arg > 0 then "positive when arg < 0 then "negative else "zero" end end meth_two(23) # => "positive" meth_two(0) # => "zero"
Ruby的return可以是一外语句块。也常用于循环时跳出
#方法可以返回多个值 def meth_three 100.times do |num| square = num*num return num, square if square > 1000 end end meth_three # => [32, 1024] #可以使用多个接收参数 num, square = meth_threee
Splat!Expanding Collections in Methond Calls
#参数可以由集合或者可迭代对象转换而来 def five(a, b, c, d, e) "I was passed #{a} #{b} #{c} #{d} #{e}" end five(1, 2, 3, 4, 5 ) # => "I was passed 1 2 3 4 5" five(1, 2, 3, *['a', 'b']) # => "I was passed 1 2 3 a b" five(*['a', 'b'], 1, 2, 3) # => "I was passed a b 1 2 3" five(*(10..14)) # => "I was passed 10 11 12 13 14" five(*[1,2], 3, *(4..5)) # => "I was passed 1 2 3 4 5" 注意,参数个数一定要对应的上,如果调用时多了或少了,都会抛出错误
Making Blocks More Dynamic
print "(t)imes or (p)lus"
operator = gets
print "number:"
number = Integer(gets)
if operator = ~ /^t/
calc = lambda {|n| n*number}
else
calc = lambda {|n| n+number}
puts((1..10).collect(&calc).join(", "))
produces:
(t)imes or (p)lus: t
number: 2
2, 4, 6, 8, 10, 12, 14, 16, 18, 20
#如果方法参数的最后一个使用&作为前缀,ruby认为它是一个Proc对象,会把它从参数列表中删除,并转为一个块代码供内部调用。
#这里不明白(1..10).collect方法的语
Hash及关键字参数
#:titles表示希望返回的内容,第二个参数是参数hash class SongList def search(field, params) # ... end end list = SongList.new list.search(:titles, { genre: "jazz", duration_less_than: 270 }) 有一个快捷的写法: list.search(:titles, genre: "jazz", duration_less_than: 270) ruby会自动把它们组装为一个hash传给方法。
Keyword Argument Lists
#下面这个方法需要判断入参的hash中是否有其它非法参数
def search(field, options)
options = { duration: 120 }.merge(options)
if options.has_key?(:duration)
duration = options[:duration]
options.delete(:duration)
end
if options.has_key?(:genre)
genre = options[:genre]
options.delete(:genre)
end
fail "Invalid options: #{options.keys.join(', ')}" unless options.empty?
#如果options不为空,则表示有非法的参数,就失败
# rest of method
end
#在Ruby 2中,可以在方法中定义关键字参数,然后Ruby会自动将值设给对应的参数。
并且会进行参数校验
--------------------这些是2.0的语法-----------------------
结束。