注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 Pass4sure CCNA640-802 v3..
 帮助

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


2008-06-24 00:34:46
 标签:Ruby 语法 Alex学Ruby   [推送到技术圈]

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://blackanger.blog.51cto.com/140924/83699
符号:
========你知道吗?

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]

不能不包含其起点。。。

本文出自 “{ :Alex Space => " Ruby Notes " }” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/83699





    文章评论
 <<   1   2   >>   页数 ( 1/2 )  
2008-07-07 23:56:21
为什么?
>> r1 = "3".."5"
=> "2".."5"
>> s = "28"
=> "28"
>> r1.include?(s)
=>false
我刚学很菜,能给我细讲下原理吗?
如何能更直观的看出结果

2008-07-11 00:33:38
晕。范围,3到5是指,3.4,5这个范围,28当然不在这范围里了。 所以你用include?判断,返回是false

2008-07-11 16:50:40
那个我范围我打错2..5了
有没有不用include?直接能看出结果

2..5就是真
3..5就是假
刚开始我想的2..5表示2到5这个范围,3..5表示3到5这个范围.
28既然在2..5是真,那麽3..5也应该是真.
要是面试直接问这样的题,不让我在机子上用include?我如何知道结果???

2008-07-11 17:44:44
你的思维有点混乱吧,28不在2.。5和3.。5的范围啊,眼睛一看就看出来了啊,区间,初中数学知识。

2008-07-12 07:45:17
你的思维有点混乱吧,28不在2.。5和3.。5的范围啊,眼睛一看就看出来了啊,区间,初中数学知识。



28在2..5是真啊.
怎么一眼看出啊.难道就是因为28不是2..5的数字
那它应该是假啊

2008-07-12 15:54:59
>> a = 2..5
=> 2..5
>> a.include?(28)
=> false

我对你实在是无语了。

2008-07-12 15:56:18
你是哪个精神病院跑出来的啊

 <<   1   2   >>   页数 ( 1/2 )  

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: