最近一直在看Programming Ruby - 2nd, 先记录下一些不熟悉的Ruby的基本语法和操作(熟悉的就不再记啦...)
Ruby的命名:
局部变量 全局变量 实例变量 类变量 常量和类名
==============================================================================
name $debug @name @@total PI
fish_and_chips $CUSTOMER @point_1 @@symtab FeetPerMile
x_axis $_ @X @@N String
thx1138 $plan9 @_ @@x_pos MyClass
_26 $Global @plan9 @@SINGLE JazzSong
==============================================================================
数组:
数组下标从0开始, 下标可以为负整数, 此时代表数组从最末端开始, 最末端索引从-1开始
数组的元素可以是任何类型的对象实例,包括nil实例
数组的初始化:
a = [ 'ant', 'bee', 'cat', 'dog', 'elk' ]
或者
a = %w{ ant bee cat dog elk }
访问:
a[0] #返回"ant"
a[1] #返回"bee"
a[-1] #返回"elk"
a[-2] #返回"dog"
赋值:
a = [ 1, 3, 5, 7, 9 ]
a[1] = 'bat' #a = [1, "bat", 5, 7, 9]
a[3]= 'cat' #a = [1, "bat", "cat", 7, 9]
a[3] = [ 9, 8 ] #a = [1, "bat", "cat", [9, 8], 9]
a[6] = 99 #a = [1, "bat", "cat", [9, 8], 9, nil, 99]
a = [ 1, 3, 5, 7, 9 ]
a[2, 2] = 'cat' #a = [1, 3, "cat", 9]
a[2, 0] = 'dog' #a = [1, 3, "dog", "cat", 9]
a[1, 1] = [ 9, 8, 7 ] #a = [1, 9, 8, 7, "dog", "cat", 9]
a[0..3] = [ ] #a = ["dog", "cat", 9]
a[5..6] = 99, 98 #a = ["dog", "cat", 9, nil, nil, 99, 98]
哈希表:
相当于Java中的Map
具有"键值对"特性, key和value都可以是任何类型的实例
哈希的初始化:
h = Hash["a", 100, "b", 200] # {"a"=>100, "b"=>200}
h = Hash["a" => 100, "b" => 200] # {"a"=>100, "b"=>200}
h = { "a" => 100, "b" => 200 } # {"a"=>100, "b"=>200}
访问:
h.length = 2
赋值:
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
h.length # 3
h['dog'] # "canine"
h['cow'] # 'bovine'
h[12] # 'dodecine'
h['cat'] = 99
h # {"cow"=>"bovine", "cat"=>99, 12=>"dodecine","donkey"=>"asinine", "dog"=>"canine"}
代码块:
代码块在ruby 中是以{} 和do end 来包围起来的。通常如果是单行使用{} ,如果是多行使用do..end
代码块可以接受参数, 参数用两个竖线"|"符号来包含, 参数间用逗号","来分隔
代码块被作为一个对象传入method体中执行(如果代码块对象有参数, 则method体在执行代码块中的代码前,需要对代码块对象的参数赋值)
例如:
def test(max)
i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1)
while i1 <= max
yield i1 # 也可以写成yield(i1), yield指令代表了代码块执行的位置, i1是method体中对代码块f进行了赋值
i1, i2 = i2, i1+i2
end
end
test(1000) {|f| print f, " " }
输出: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
又例如:
[1,3,5,7].inject(0) {|sum, element| sum+element} # 输出:16
Method的声明:
一般格式是:
def my_new_method(arg1, arg2, arg3) # 3 arguments
# Code for the method would go here
end
方法名initialize是特殊的method, 它在类的new操作时被执行, 用于对类实例进行初始化操作:
def initialize(name, &block)
@name, @block = name, block
end
如果需要方法返回一个值, 可以显式使用return关键字, 也可以使用"默认最后一行返回值"形式:
def meth_one
"one" # 相当于 return "one"
end
如果method的声明中最后的参数带有"&"前缀(例如下例的&action), 则表示该参数接受的是代码块, 并且该代码块将被转换为Proc对象, 最后被赋值给一个类实例变量,如:
class JukeboxButton < Button
def initialize(label, &action)
super(label)
@action = action #代码块对象被赋值给一个类实例变量(即@action)
end
def button_pressed
@action.call(self)
end
end
start_button = JukeboxButton.new("Start") { songlist.start }
如果method的声明中最后的参数带有"*"前缀, 表示该参数接受的是0个或多个参数(即:可变长参数), 例如:
def varargs(arg1, *rest)
"Got #{arg1} and #{rest.join(', ')}"
end
varargs("one") # "Got one and "
varargs("one", "two") # "Got one and two"
varargs "one", "two", "three" # "Got one and two, three"
如果method的方法名最后为字符"=", 表示该方法可为类实例变量赋值, 相当于Java中的setXXXX方法
class Song
def duration=(new_duration) # 整个方法名为"duration="
@duration = new_duration # @duration为类实例变量
end
end
song = Song.new("Bicylops", "Fleck", 260)
song.duration # 260
song.duration = 257 # set attribute with updated value
song.duration # 257
上例中的"duration="方法 相当于下面的: attr_writer :duration
class Song
attr_writer :duration
end
song = Song.new("Bicylops", "Fleck", 260)
song.duration = 257
区间:
两个点创建一个"包含"区间
1..10 #包含1和10
'a'..'z'
三个点创建一个除最后一个元素外的区间
my_array = [ 1, 2, 3 ]
0...my_array.length # 相当于0..2
区间可以通过to_a函数来转换为数组
a = (1..3).to_a # a = [1, 2, 3]
区间的一些方法:
digits = 0..9
digits.include?(5) # true
digits === 5 # true
digits.min # 0
digits.max # 9
digits.reject {|i| i < 5 } # [5, 6, 7, 8, 9]
digits.each {|digit| dial(digit)} # 0..9
待续...