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

本文深入探讨了Ruby语言中符号(Symbol)的特点与应用场景,包括内存效率、实例变量设置及符号到字符串的转换等。同时,文章还介绍了Ruby中范围(range)的概念、创建方式及其在迭代中的行为特点。
摘要由CSDN通过智能技术生成
符号:
========你知道吗?

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]

不能不包含其起点。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值