注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

FY

Johnson 's Blog

 
 
 

日志

 
 

perl范围操作符 ..  

2011-12-14 16:40:33|  分类: perl |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

链接出处
Perl的范围操作符 .. 在标量环境中具体是怎样执行的?

左操作数、右操作数和..操作符的布尔状态各是怎样转换的?
########################################################
在标量环境里,.. 返回一个布尔值。该操作符是双稳定的,类似一个电子开关,并且它仿真 sed,awk,和各种编辑器的行范围(逗号)操作符。每个 .. 操作符都维护自身的状态。只要它的左操作数为假就一直为假。一旦左操作数为真,该范围操作符就保持真的状态直到右操作数为真,右操作数为真之后该范围操作 符再次为假。该操作符在下次计算之前不会变成假。它可以测试右操作数并且在右操作数变真后在同一次计算中变成假(awk 的范围操作符的特性),不过它还是会返回一次真。如果你不想拖到下一次计算中才测试右操作数(也是 sed 的范围操作符的工作方式),只需要用三个点(...)代替两个点(..)。对于 .. 和 ...,当操作符处于假状态后就不再测试右操作数,而当操作符处于真状态后就不再测试左操作数。

返回的值要么是代表假的空字串或者是代表真的一个序列数(从 1 开始)。该序列数每次碰到新范围时重置。在一个范围里的最后序列数后面附加了字串“E0”,这个字串不影响它的数字值,只是给你一些东西让你可以搜索,这 样你可以把终点排除在外。你也可以通过等待 1 的序列数的方法把启始点排除在外。如果标量 .. 的某个操作数是数字文本,那么该操作数隐含地与 $.变量对比,$. 里包含你的输入文件的当前行号。

原书中是这样讲的,小弟初学,请您详细讲解一下好吗?谢谢了~
########################################################
如下代码

foreach my $x ( 1..10 ){print $x if $x == 3..$x >= 3}     # 只打印 3
foreach my $x ( 1..10 ){print $x if $x == 3...$x >= 3}    #打印 3 和 4

按照大骆驼中的规则解释第一行代码:1、在1..10的范围内,$x被反复赋值,整个表达式的初始布尔状态为假,并且当$x值为1和2时一直为假
                                  2、以3为临界点,当$x的值为3时,布尔状态切换为true并返回true,一直保持true的状态,同时继续测试右操作数
                                  3、当$x的值为4时,布尔状态切换为false,且在$x>3时一直为false
                                                        整个表达式只有在$x的值为3时为true,所以最后只打印3
按照上面的方式和过程理解正确吗?

如果正确的话那么,

问题1:>=表示大于或者等于,但是为什么当$x的值为4 5 6 7 的时候布尔值为假呢?

问题2:两点..范围操作符和三点...范围操作符有什么区别,书上面说“它等到下一次求值的时候才测试其右侧表达式”,这句话应该怎样理解?

问题3:foreach my $x ( 1..10 ){print $x if $x == 3...$x <= 3} 执行的结果为打印 3 4 5 6 7 8 9 10,更加困惑,求解!

跪求高手指点小弟一下,谢谢!

########################################################
In scalar context, ".." returns a boolean value.  The
     operator is bistable, like a flip-flop, and emulates the
     line-range (comma) operator of sed, awk, and various
     editors.  Each ".." operator maintains its own boolean
     state.  It is false as long as its left operand is false.
     Once the left operand is true, the range operator stays true
     until the right operand is true, AFTER which the range
     operator becomes false again.  It doesn't become false till
     the next time the range operator is evaluated.  It can test
     the right operand and become false on the same evaluation it
     became true (as in awk), but it still returns true once.  If
     you don't want it to test the right operand till the next
     evaluation, as in sed, just use three dots ("...") instead
     of two.  In all other regards, "..." behaves just like ".."
     does.
########################################################
foreach my $x ( 1..10 ){print $x if $x == 3..$x >= 3}     # 只打印 3
$x为3的时候判断一下前面的为真,整个操作符就为真,继续判断后面的也为真,AFTER 然后3之后操作符就为假,所以4就是假了

foreach my $x ( 1..10 ){print $x if $x == 3...$x >= 3}    #打印 3 和 4

$x为3的时候判断一下前面的为真,整个操作符就为真,但是到下一个$x也就是4才判断后面的条件,于是到4的时候判断后面为真,AFTER 整个操作符为假,所以4之后的就是假,3和4为真

多看几遍就明白了
###############################################################

附:
链接出处
今天学习到的一种比较新的,挺有趣的特性,说新只是以前学JAVA和PHP的时候木有接触过。貌似Ruby的这一特性是从Perl那里继承而来,所以学习过Perl的程序员应该比较熟悉。
     flip-flop
以下内容摘自《Ruby编程语言》
     当..和...操作符被用在一个条件式,或者一个循环中时,它们不会创建Range对象。相反地,它们将创建一种特殊的布尔表达式,名为flip-flop.和比较以及相等表达式一样,一个flip-flop表达式的值也为true或者false。但是一个flip-flop表达式的特殊之处在于,它的值依赖于此前的求值结果,这就意味着flip-flop表达式具有与其关联的状态,所以你可能会认为一个flip-flop是一个某种类型的对象,但事实上flip-flop并不是对象,而是Ruby表达式。Ruby解释器在处理完一个flip-flop表达式之后,将为它在内部存储一个解析后的表现形式,其中就保存了该表达式的状态(只是作为一个布尔值)。
有了这些背景知识后,请看下面代码中的flip-flop。第一个..创建一个Range对象,第二个..则创建了一个flip-flop表达式:
               (1..10).each {|x| print x if x==3..x==5 }
    在一个由条件式或者循环所构成的上下文中,一个flip-flop由两个通过..操作符相连的布尔表达式构成。除非其左侧表达式为true,否则一个flip-flop表达式就位false,而且在左侧表达式为true之前,它的值都会是false。一旦该表达式为true那么它就会“flips”到一个持久的true状态。它会保持该状态,而且对其后续的求值也返回true,直到其右侧的表达式为true为止。如果右侧表达式为 true了那么该flip-flop就会“flops”回一个持久的false状态,对其后续的求值也返回false,直到其左侧表达式再次成为true为止。
    在上面的代码例子中,该flip-flop被反复求值,相应的x的值也从1增加到10.起初,它的状态为false,而且在x等1和2的时候一直是false。当x等于3的时候,该flip-flop的状态就成为true。在x等于4和5的时候,该flip-flop的状态又回到了false,而且对于后续的x,它总是返回false。上述代码的执行结果是打印出345 。
    可以使用..或...来编写flip-flop。起差别在于:当一个..flip-flop为true时,它会返回true,同时测试它的右侧表达式以决定是否需要将其内部状态设置回false;而对于...flip-flop来说,它等到下一次求值的时候才测试其右侧表达式。观察下面的代码:
  1. # Prints "3"  .  Flips and flops back  when x==3
  2. (1..10).each {|x| print x if x==3..x>=3}
  3. # Print "34" .   Flis when x==3 and flops when x==4
  4. (1..10).each {|x| print x if x==3...x>=3}
复制代码
注:flip-flop其中一个意思是突变,flip和flop都有翻转的意思
  评论这张
 
阅读(386)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018