2.8. 核心语言——对象,类,方法-3
参数个数
用过少或过多的参数去调用方法都是错误的。一个方法接收的参数一定不能少于必须参数的个数,也一定不能多于定义中参数的个数总和。参数个数不对的方法调用将会抛出一个异常。
*前缀来设置可选参数
可选参数不仅可以通过我们前面说的赋值语句来设置,还可以通过 *
或者 splat 操作符 来设置。如果一个方法的最后一个参数的前缀是 *
,那么任何非必须的参数都会作为一个列表传递给它。
class ListChanger
def change_list(list, *values)
values.each { |v| list.push(v) }
end
end
changer = ListChanger.new
array = [1, 2, 3]
changer.change_list(array, 4, 5, 6)
print array # [1,2,3, 4,5,6]
*前缀来传递数组
通过增加一个 *
前缀 ,一个数组也可以传递给一个期待多个参数的方法。
class ListChanger
def change_list(list, *values)
values.each { |v| list.push(v) }
end
end
changer = ListChanger.new
array = [1, 2, 3]
args = [array, 7]
changer.change_list(*args)
print array
*扁平化数组
*
还可以用来扁平化数组。比如一个大数组里面还包括一个小数组。如果在这个小数组前面加上 *
,那么它就可以得到一个把这个小数组打散到这个大的数组里面。
➜ A.2.3 git:(daily) ✗ irb
irb(main):001:0> print [1, 2, *[3, 4]]
[1, 2, 3, 4]=> nil
实例变量
为了做一些有趣的事情,对象需要内部状态。在 Ruby 里,这个状态被包含在实例变量里面,它的前缀是符号@ 。实例变量不需要提前声明,就能够在一个对象的任何方法里面被赋值和访问。通常是在对象的 initialize 方法里面对他们进行赋值——该方法是在通过调用 new 方法实例化新的对象时被隐式调用的。
class Robot
def initialize(name)
@name = name
end
def say_hello
puts "hello, I'm #{@name}"
end
end
bot = Robot.new("Marvin")
puts bot.say_hello # prints "hello, I'm Marvin"
实例变量的作用域是在这个对象里面。类的每一个实例的实例变量都会有自己的值,这些变量能够通过这个对象的任何对象方法进行访问。对那些还没有定义的实例变量的引用会计算出 nil
值,而不是抛出一个错误。虽然说 Ruby 可能会打印关于它的一个警告。
*Note: #{}
与 JavaScript 中的 ${}
的作用相同。
局部变量
局部变量没有前缀 @ 的,它的作用域是在方法体的 def 和 end 之间。在方法返回之后,他们就不复存在了。引用一个不存在的局部变量是会发生错误的。一个变量可能被定义,但是值为 nil
,这个情况是和变量本身不存在是不同的。
全局变量
全局变量前缀是 $,在整个程序中可见。有些操作比如匹配正则表达式,会隐含的创建包含正则匹配结果的全局变量,但我们将不会使用它们。