作者CindyLinz (Cindy Wang)
看板Perl
标题Re: [问题] 点点(..)运算子两问
时间Mon Oct 28 15:25:11 2013
※ 引述《AntaresStar ()》之铭言:
: 对一个array我们可以用@arr[1..2]这样的方式取到subarray
: 但对一个array ref 用箭头$arr_ptr->[1..2]这样会只取到其中一个值
: 看不太出规律 而又不会error
: 有人知道是为什麽吗
: 另外一个问题
: 有人知道4个点的用途吗
: perl -e 'print 1..2' # 12
: perl -e 'print 1...2' # 12
: perl -e 'print 1....2' # (print nothing)
: perl -e 'print 0....2' # 0
: perl -e 'print 1.....2' # syntax error at -e line 1, near "....."
: 网路上查到的多半都是2点跟3点的差异 找不到4点的
: --
:
※ 发信站: 批踢踢实业坊(ptt.cc)
: ◆ From: 111.248.84.243
: ※ 编辑: AntaresStar 来自: 111.248.84.243 (10/27 21:53)
: 推 scwg: ->[ ] 的 index 不是 list context, 而是 scalar context 10/28 06:25
: → scwg: 1..2 的 scalar context 解读和 list context 不一样 10/28 06:25
: → scwg: e.g. $arr_ptr->[1,3,5] 相当於 $arr_ptr->[5], 不是 10/28 06:27
: → scwg: @{$arr_ptr}[1, 3, 5] 10/28 06:27
: 推 cutekid:推 scwg 解释(Y) 10/28 09:28
: → scwg:那再推一个 xd 这个是猜的, 四个点是被拆成 0 ... .2 从 0 到 10/28 09:39
: → scwg: 0.2, 所以是一个 0. 1 ... .2 则是空的 10/28 09:39
: → scwg: 手边没有 perl 有编-DDEBUGGING不然应该用 -Dx 看parse tree 10/28 09:40
: 推 cutekid:哇,scwg 太强了,再推一次有关 4 个点的「猜想」 10/28 10:57
: → AntaresStar:刚刚用-10....2试了一下 0.2的猜想应该是对的 10/28 13:11
: → AntaresStar:关於第一个问题 那1..2的scalar context要怎麽解读呢 10/28 13:13
: → AntaresStar:看来是被当成range operator了 这真是太奇怪了 XD 10/28 13:17
: 推 CindyLinz:是 flip-flop 正反器.. 至於实用情境嘛... (思) 10/28 15:02
.. 和 ... 用在 scalar 时像是「正反器」, 用起来也像是正反器,
对我这不是电子电路出身的人来说, 初看时还真不知道能怎麽用.. :Q
它的说明非常地.. 像零件...
「起初, 如果左边是 false, 则它是 false;
如果一旦左边变成 true 了, 则它会先变成 true, 然後开始看右边..
(如果是『..』的话, 这一次就先仍不管右边,
如果是『...』的话, 如果右边现在已是 true,
则下一次会跳回起初一样看左边.)
继续, 就一直观察右边, 如果右边是 false, 则继续 true 下去看右边;
如果右边是 true, 那这一次仍维持 true, 但下一次会变回起初状态.
」
我觉得用起来一个自然的用法是这样:
while(<>) {
if( /begin/ ... /end/ ) {
print $_;
}
}
那麽如果输入内容如下
a
begin
b
c
end
e
会印出
begin
b
c
end
而 .. 和 ... 的差别在
begin xyz end
oo
end
这种, begin 和 end 出现在同一行的时候,
... 的版本会印出
begin xyz end
.. 的版本会印出
begin xyz end
oo
end
因为 .. 在 begin 的那一刻就不会去看右边的条件, 而 ... 会.
btw, .. / ... 决定要看左边或右边的「状态」, 会跨越函数呼叫,
所以可以把这东西放在一个 sub processLine {} 里面,
然後每一行资料去呼叫它一次也会动~
然後 .. / ... 还有一个隐藏功能,
如果 .. / ... 的左边或右边是个「常数」的话,
它会拿这个常数去跟 $. 作 == 的比较...
($. 是目前正在读的档案的行号)
所以可以写
while(<>){
if( 3 .. 5 ) {
print $_;
}
}
会印出 3~5 行~
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 112.121.80.249
1F:推 cutekid:推(Y),长知识 10/28 16:06
2F:→ cutekid:请问「跨越函数呼叫」那边有例子吗?不是很了解 ^_^ 10/28 16:06
3F:推 abliou:太棒了! 10/29 12:38
4F:推 abliou:这样太好用了啦!这省去我以前最少40行的程式码阿! 10/29 14:13
5F:推 NEWORDER:推 10/30 14:50
右边的 true/false 在说明里写反了 :p
不过我猜这麽细节的部分没有人看 XD
※ 编辑: CindyLinz 来自: 112.121.80.249 (10/31 13:55)