符号:
========你知道吗?
Ruby 里Symbol的实例就是一符号。
每个符号只有一个实例对象(类似于Fixnum)。
arr = ["foo","foo","foo",:bar,:bar,
:bar]
数组arr里的三个foo字符串分别是独立的三个对象,而那三个:bar是同一个字符对象的三个引用,所有有种说法,符号比字符串节省内存,可提高性能。
一个符合对应一个数字,存储为直接值。 可以使用to_i获取该数字。
>> :bar.to_i
=> 20041
>> :foo.to_i
=> 14585
========你知道吗?
一个把字符当作元值的例子:假设一个从网络中获取字符串的方法,可在发生异常时返回非字符串的值。
str = get_string
case str
when String
...
when :eof
#end of file, socket colosed, whatever
when :error
#I/O or network error
when :timeout
# didnt get a reply
end
看起来比异常处理要好,
========你知道吗?
又一个例子:
>> sym1 = :@foo
=> :@foo
>> sym2 = :foo
=> :foo
>> instance_variable_set(sym1,"str1")
=> "str1"
>> instance_variable_set(sym2,"str1")
NameError: `foo' is not allowed as an instance variable name
如果用instance_variable_set必须指定准确的变量名。
========你知道吗?
>> :bar.to_s
=> "bar"
>> :bar.to_str
NoMethodError: undefined method `to_str' for :bar:Symbol
from (irb):10
>> "bar".to_sym
=> :bar
to_s和to_sym方法来进行字符串和符号之间的转换。
========你知道吗?
list = words.map{|x| x.upcase}
我们可以在Symbol类里定义一个to_proc方法,
def to_proc
proc{ |object,*args| object.send(self,*args) }
end
有了这段代码我们可以重写:
list = words.map(:&upcase)
解释: map方法只接受代码块,通过使用&可传递proc,来代替显示的使用代码块。而这个时候&被应用于不是proc的对象,而传进来的本身是个符号对象(:&upcase),所以解释器自然而然的就会调用符号类的to_proc方法来得到一个proc。to_proc方法里的self引用的是对其调用了to_proc的符号。
-------------------------------------->>>>>>>>>>>>>>>>>>>>>
范围:
范围的起点和终点可以是任何Ruby对象,范围一般用于迭代。
========你知道吗?
>> r1 = "7".."9"
=> "7".."9"
>> r2 = "7".."10"
=> "7".."10"
>> r1.each{|x| puts x}
7
8
9
=> "7".."9"
>> r2.each{|x| puts x}
=> "7".."10"
两个看起来相似的范围对象,为什么迭代以后就有了不同的值呢 ?
原因在于第二个范围对象r2, 其终点是长度不同于r1终点的字符串。对r2进行迭代的时候,一般是以当当前值大于终点值时候结束循环,而字符串"7" 是大于"10"的,所以根本没有循环。用作终点的类,必须定义了有意义的succ方法。 不能对浮点数范围进行迭代,因为浮点数没有succ方法。
>> "7" > "10"
=> true
要随时注意使用的范围是否是字符串范围,否则会得到意想不到的结果:
>> r1 = "2".."5"
=> "2".."5"
>> s = "28"
=> "28"
>> r1.include?(s)
=> true
========你知道吗?
将范围用于条件句中,将被特别对待,. . 这种用法这个时候被称为flip-flop运算符。 有个例子,想输出一个ruby文件里=begin和=end之间的line。
loop do
break if eof?
line = gets
puts line if (line =~ /=begin/) .. (line =~ /=end/)
end
像这种根本不是范围,这个时候不能把它当范围来认知。
========补充
Ruby的遗憾是:
(1..5).to_a #=> [1,2,3,4,5]
(1...5).to_a #=> [1,2,3,4]
不能不包含其起点。。。
©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任
职场Ruby休闲