Alex学Ruby[告诉你符号和范围的真相]

符号:
========你知道吗?

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]

不能不包含其起点。。。

你可能感兴趣的:(职场,Ruby,语法,休闲,Alex学Ruby)