Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no no-op #7470

Closed
p5pRT opened this issue Aug 18, 2004 · 40 comments
Closed

no no-op #7470

p5pRT opened this issue Aug 18, 2004 · 40 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 18, 2004

Migrated from rt.perl.org#31228 (status was 'resolved')

Searchable as RT31228$

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2004

From @jidanni

Gentlemen, perl has no no-op.
The shell has its "​:" operator, but in perl, all one can find is
$ perldoc perlop|grep no-\\?op
  @​foo = @​foo[0 .. $#foo]; # an expensive no-op
perldoc -q finds none too.

Why should perl have a no-op? Well, let's say we have a complicated
patch of code that we want to turn a little part of off.
Say the "next" in​:
  next if [....miles and miles of code....]
Well, we could use
  my $dumb=0 if [....miles and miles of code....]
But that looks dumb. Therefore Perl should allow
  noop if [....miles and miles of code....]
[The miles and miles of code still get evaluated, but that's not the
issue here.]

No need to name the new no-op operator after me, just add it to the
language, or at least mention the preferred way to do a no-op on perlop.

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2004

From @rgs

Dan Jacobson (via RT) wrote​:

Gentlemen, perl has no no-op.

The usual practice is to use a bare C<;> or C<1> (which is even
special cased in the parser to avoid generating warnings
on things like C<1 while foo()>).

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2004

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2004

@rgs - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Aug 19, 2004
@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2004

From @jidanni

Rafael> The usual practice is to use a bare C<;> or C<1> (which is even
Rafael> special cased in the parser to avoid generating warnings
Rafael> on things like C<1 while foo()>).

No so fast. Let me try it.

$ perl -we 'C<1> if 1'
syntax error at -e line 1, near "1>"
Execution of -e aborted due to compilation errors.

Why don't you explain what you are talking about in an addition to
perldoc perlop.

Trying again.
$ perl -we 'C<1 if 1>'
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
$ perl -we '1 if 1'
$

Well, while typing around, I have discovered a simple no-op​: 1.
Works better than
$ perl -we '; if 1'
syntax error at -e line 1, near "if 1"
Execution of -e aborted due to compilation errors.
$ perl -we '{;} if 1'
syntax error at -e line 1, near "if 1"
Execution of -e aborted due to compilation errors.
$ perl -we '{} if 1'
Useless use of single ref constructor in void context at -e line 1.

Anyways, my point stands​: Perl has not documented how to do a no-op.
The logical point to put it is perlop.

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From RandyS@ThePierianSpring.org

On 8/19/2004 6​:23 PM, Dan Jacobson wrote​:

Rafael> The usual practice is to use a bare C<;> or C<1> (which is even
Rafael> special cased in the parser to avoid generating warnings
Rafael> on things like C<1 while foo()>).

No so fast. Let me try it.

$ perl -we 'C<1> if 1'
syntax error at -e line 1, near "1>"
Execution of -e aborted due to compilation errors.

err, the C<> notation is POD style markup. It's also used as a
convention to quote code snippets in messages. Try either of​:

$ perl -we '1 if 1'

$ perl -we 'do{} if 1'

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From @tamias

On Fri, Aug 20, 2004 at 06​:23​:48AM +0800, Dan Jacobson wrote​:

Rafael> The usual practice is to use a bare C<;> or C<1> (which is even
Rafael> special cased in the parser to avoid generating warnings
Rafael> on things like C<1 while foo()>).

No so fast. Let me try it.

$ perl -we 'C<1> if 1'
syntax error at -e line 1, near "1>"
Execution of -e aborted due to compilation errors.

C<> is POD markup, used to distinguish code from text. Look at the
unrendered documentation some time.

Well, while typing around, I have discovered a simple no-op​: 1.

Yes, that's Rafael was telling you in the first place.

Ronald

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

usually, the solution to the problem is a module​:

te@​linux​:~> cat nop.pm
package nop;

use strict;
use warnings; # not for older perls?
require Exporter; # could use Exporter​::Lite
use vars qw/@​EXPORT/;
@​EXPORT = qw/nop/;

sub nop () { 1; }

te@​linux​:~> perl -Mnop -le 'nop for ("a" .. "z"); print nop;'
te@​linux​:~>

(I choose nop because it reminds me of assembler, is one letter shorter and
doesn't sound like "poop").

If there is sufficient interest, that could hit CPAN - but I doubt it. Sick
people might even use a source code filter..

In related news, there is also '...', which is often used as a placeholder,
but doesn't seem to work in actual code​:

te@​linux​:~> perl -le '... for ("z".."z")'
syntax error at -e line 1, near "..."
Execution of -e aborted due to compilation errors.

I am not sure if it is possible to have a subroutine named '...', though :)

Best wishes,

Tels

- --
Signed on Fri Aug 20 13​:52​:03 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

The best thing about growing older is that it takes such a long time.

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQSXnAncLPEOTuEwVAQE24Qf+J1MNaDBCnSnSy+UDr/3gJhdMttD/x64D
+p0AlO8TnstBUDgCGANX7/YO2n00KyiN4s/7vWZ0iwfU32Jq94O9tAHI2qy4DKre
Ncs3voFGjcEw4FkBMLWKTDPWrC9Hk0Xw3OXdXZ+PY4LWe0MBKoAwiPu96Whj0f0v
8luzSpDy6S8BXOA0IThb8qDUvbQ/ewpXY4pz8rt7hDhybZCAzJddA2IEaZVX6xuK
bs5wMUP/N+Q9fSOL31zBGergbmjqDFgwCSziDbUgleh6S7bxXXvK1m1H7Qsr4kXn
Z0L5a5RtyT2sQ8uBlKdMw1rdXRTuG/BDcjB5/iqMOAkdfP5FaTyBwA==
=aDTW
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From @nwc10

On Fri, Aug 20, 2004 at 01​:56​:42PM +0200, Tels wrote​:

In related news, there is also '...', which is often used as a placeholder,
but doesn't seem to work in actual code​:

te@​linux​:~> perl -le '... for ("z".."z")'
syntax error at -e line 1, near "..."
Execution of -e aborted due to compilation errors.

I made a patch to implement ... (well, at least part of its perl6
functionality) and sent it to p5p some time ago. IIRC it got mostly
Warnocked. However, these days it seems more appropriate for the aim of
5.10, so I might try to dig it out.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From @RandalSchwartz

"Tels" == Tels <perl_dummy@​bloodgate.com> writes​:

Tels> sub nop () { 1; }

This is not a nop. If it were truly a nop, then these two subroutines
would return the same thing​:

sub first { 5; }
sub second { 5; nop(); }

We need a no-op that doesn't affect "last expression evaluated".

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@​stonehenge.com> <URL​:http​://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From @rgs

Randal L. Schwartz wrote​:

"Tels" == Tels <perl_dummy@​bloodgate.com> writes​:

Tels> sub nop () { 1; }

This is not a nop. If it were truly a nop, then these two subroutines
would return the same thing​:

sub first { 5; }
sub second { 5; nop(); }

We need a no-op that doesn't affect "last expression evaluated".

And what should do​:

sub f { nop; }
sub g { 5; f; }
print g;

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From rick@bort.ca

On Fri, Aug 20, 2004 at 08​:24​:57PM +0200, Rafael Garcia-Suarez wrote​:

And what should do​:

sub f { nop; }
sub g { 5; f; }
print g;

Obviously that prints an empty list. But

  sub f () { nop; }

should be inlined-out so that it prints 5. ;-)

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Aug 20, 2004

From @jidanni

All this is above the beginning user's head.
Please add something like this to perlop​:
NO-OP​:
  One can use 1 or 0 if one needs a no-op.
  e.g., to do nothing instead of
  bla() if ...
  use
  1 if ...

  1 returns 1, and 0 returns 0.

However, this still may be too abstruse.

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From whatever@davidnicol.com

On Fri, 2004-08-20 at 07​:21, Nicholas Clark wrote​:

I made a patch to implement ... (well, at least part of its perl6
functionality) and sent it to p5p some time ago. IIRC it got mostly
Warnocked. However, these days it seems more appropriate for the aim of
5.10, so I might try to dig it out.

Nicholas Clark

Is the current behavior of threedots deprecated?

from perlop​:

  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 edi­
  tors. 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.

--
david nicol
  "Someday, everything's going to be different
  when I paint my masterpiece."

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From ajs@ajs.com

Dan Jacobson wrote​:

All this is above the beginning user's head.
Please add something like this to perlop​:
NO-OP​:
One can use 1 or 0 if one needs a no-op.
e.g., to do nothing instead of
bla() if ...
use
1 if ...

   1 returns 1\, and 0 returns 0\.

However, this still may be too abstruse.

It's a bit hard to make out. If you really feel that perlop needs such a
thing (is perlop the right place for it?), then I would say something like​:

  Perl has no "no-op" facility per se, but it is conventional to use
  a constant number 1 in places where you wish to do no work, as in​:

  $_ = "aaaabbbb";
  1 while s/ab//;

  There is nothing particularly interesting about a constant 1 that
  makes it more attractive for such usage over any other number, but
  if you use 1 in these sorts of situations, Perl programmers will
  generally recognize what you mean.

I would not bother using C<1> here, but knock yourself out if you're a
fan of extra markup :)

As for Randal's assertion that a true no-op would not affect "last
expression" return values... I'm not sure I see the value of such a
thing. If you're trying to deal with the Perl equiv of the old C, "#if
0" style of blocking out code execution, then there are a host of
related limitions in Perl that fall out of its not having a default
pre-processor, and I'm not sure it's worth addressing just one such
limitation as a special case.

Dan, your original question seemed to be of the form​:

  How do I modify​:

  next if large_amount_of_work();

  so that it does nothing?

Now, I know I might be being dense here, but can't you simply comment
out the line?

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Saturday 21 August 2004 03​:38, david nicol wrote​:

On Fri, 2004-08-20 at 07​:21, Nicholas Clark wrote​:

I made a patch to implement ... (well, at least part of its perl6
functionality) and sent it to p5p some time ago. IIRC it got mostly
Warnocked. However, these days it seems more appropriate for the aim of
5.10, so I might try to dig it out.

Nicholas Clark

Is the current behavior of threedots deprecated?

from perlop​:

Oh, you learn something new each day....

In related news, when will .. and ... overloadable? :)

Cheers,

Tels

- --
Signed on Sat Aug 21 10​:38​:50 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Yeah. Whatever."

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQScKPXcLPEOTuEwVAQHCMQf/VaUHcW4Y0yIyK3THw3kwXyhYuvRzkSfc
k8IEFPYAUnZo1G2wm7ObZ8Mqh42Bwf45gboXQU3yMIMtLNH8qsZPUWLsOfecW1kn
YSjDUJP2/VdloyuHJb2tisweYyAUxv/TA8I1ZqMumgkRUJVzlzyFPuJYU0AGHzP9
ocPEyiWBxJ2qCXKfBxiMNe584lYOtYQkzho50mvtj5NmqliuKTYqeynL8gM3ffc8
pnHvA+9ta2SxZhQhexaql6aAX2s5ktIJoiNHuMyZTMWA4xfwtI+48e7gXbPhopos
EtpLFLpxID5+QIW70ydZkHNyVCKqmZfSmQDndGjg9w+TaXsrWe+sWA==
=QwCQ
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From rick@bort.ca

On Sat, Aug 21, 2004 at 10​:39​:24AM +0200, Tels wrote​:

In related news, when will .. and ... overloadable? :)

When you submit a patch? ;-) IIRC, the last time I looked at this it
was easy enough in the list case but not so much for scalar because of
the way state hangs off the OP. And then I lost interest because I
never had need of it. What would you do with it?

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Saturday 21 August 2004 15​:13, Rick Delaney wrote​:

On Sat, Aug 21, 2004 at 10​:39​:24AM +0200, Tels wrote​:

In related news, when will .. and ... overloadable? :)

When you submit a patch? ;-)

I don't think I am qualified to do this - overload.pm scares me and I dare
not to dabble in the core :-/

IIRC, the last time I looked at this it
was easy enough in the list case but not so much for scalar because of
the way state hangs off the OP. And then I lost interest because I
never had need of it. What would you do with it?

  my $a = Math​::BigInt->new(2) ** 255;
  my $b = $a + 120;

  for ($a .. $b)
  {
  ...
  }

or even​:

  perl -Mbignum -le "for (78901234567890 .. 78901234567899) { print $_; }"

:-)

Cheers,

Tels

- --
Signed on Sat Aug 21 16​:30​:03 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"My other computer is your Windows box." -- Dr. Brad (19034) on 2004-08-13
at /.

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQSdc5ncLPEOTuEwVAQGX8Qf9FW/9RV88A8wJO6OF5Tfya3W0eaOdz1Ym
R3ipAnG8aGqRxIqz39YxTZXtWQpANdITAi5N/2EGj7MPiD7SX/c6uAgkHWZrkdU9
Jnr4eDr8GtcMSPPLaVGp/mHeRJbfI9PBiaPIqWmG/0samlz8bqYRznP6nWS1fful
4dedvdfolmwucvtk5yJL5LO7KJHEIjnmYkHIJPZOvLH4arIWnatvvBvYG7h2qScR
Q04s7pJYfZf68oq2aLm+vPop/MVVert62wxzV/44GIBa0QxVUyIpdBkOldtKmp7+
wefCfoNpQp5dycLApsxvonJEqmCJssFFuz1zzBshf+utd6PXS0nu2Q==
=7PGG
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From rick@bort.ca

On Sat, Aug 21, 2004 at 04​:31​:58PM +0200, Tels wrote​:

What would you do with it?

my $a = Math&#8203;::BigInt\->new\(2\) \*\* 255;
my $b = $a \+ 120;

for \($a \.\. $b\)
  \{
  \.\.\.
  \}

or even​:

perl \-Mbignum \-le "for \(78901234567890 \.\. 78901234567899\) \{ print $\_; \}"

Ok, but really. ;-)

Anyway, aren't those taken care of by overloaded C<++>? If not, I think
that is a bug. The for loop is optimized to use C<++> so that this
would have some hope of finishing (someday)​:

  perl -Mbignum -le "for (1 .. 78901234567899) { print $_; }"

Overloaded C<..> wouldn't help there. Or here​:

  perl -Mbignum -le "@​x = (1 .. 78901234567899); for (@​x) { print $_; }"

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Saturday 21 August 2004 19​:34, Rick Delaney wrote​:

On Sat, Aug 21, 2004 at 04​:31​:58PM +0200, Tels wrote​:

What would you do with it?

my $a = Math&#8203;::BigInt\->new\(2\) \*\* 255;
my $b = $a \+ 120;

for \($a \.\. $b\)
  \{
  \.\.\.
  \}

or even​:

perl \-Mbignum \-le "for \(78901234567890 \.\. 78901234567899\) \{ print $\_;

}"

Ok, but really. ;-)

No, really thats the reason! Longstanding bug in "bignum"!

Anyway, aren't those taken care of by overloaded C<++>? If not, I think
that is a bug. The for loop is optimized to use C<++> so that this
would have some hope of finishing (someday)​:

 perl \-Mbignum \-le "for \(1 \.\. 78901234567899\) \{ print $\_; \}"

Overloaded C<..> wouldn't help there. Or here​:

 perl \-Mbignum \-le "@&#8203;x = \(1 \.\. 78901234567899\); for \(@&#8203;x\) \{ print $\_; \}"

No, ".." bypasses the "​:constant" stuff like this​:

  te@​linux​:~>
  perl -Mbignum -le 'print ref(1); for (1.. 5) { print "$_ " . ref($_); }'
  Math​::BigInt
  1
  2
  3
  4
  5

(Expected is 1 Math​::BigInt, 2 Math​::BigInt etc)

Also, watch this​:

  te@​linux​:~> perl -Mbignum -le 'my $a = 1234567890; for ($a .. $a+5) \
  { print "$_ " . ref($_); }'
  1234567890
  1234567891
  1234567892
  1234567893
  1234567894
  1234567895
  te@​linux​:~> perl -Mbignum -le 'my $a = 1234567890123456789; \
  for ($a .. $a+5) { print "$_ " . ref($_); }'
  Range iterator outside integer range at -e line 1.

".." so far rather defeats the bignum package. And as long as _any_ code
contains a ".." or "..." operator somewhere, it will break when passed a
BigInt, e.g.​:

  package Foo;
  sub foo
  {
  # works
  my $a = shift;
  my $b = $a +5;
  while ($a++ < $b) { ... }
  }
  sub bar
  {
  # breaks with BigInt passed in
  my $a = shift;
  my $b = $a +5;
  for ($a .. $b) { ... }
  }

Thats not good, since the caller of foo() or bar() shouldn't need to care
how foo() or bar() work inside.

Cheers,

Tels

- --
Signed on Sat Aug 21 19​:36​:29 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Yeah, baby, yeah!"

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQSeJr3cLPEOTuEwVAQFxIgf/U/UthcjdIOl87/MJQdjLES76R0PeUbv7
DiX9hiw447y3J2FoySoUMNIDTFc71BQNVcf2xFhuV9tO2/4apR1JIMAJMzVnMoyL
qdr94cfG1qs7TyiBiaGSfu3kD2pJTBPGadwUkCE64DOlhFz35OkuGiVTvEQ2xtfR
N/kNESYT4Plp76IzfhYIrgB5V6iGjEg/+YRvyfSHBWInM4FPwyn3796+7iyLnXh4
5tEbs5fEko5AiILezEuPBrS32yJArvqarC1UigV0xBH90BHb0Y6A4ewx9gmxjwA7
Qt8xpuwWZfl8SkT9hTB33qJHy4OGHmkZNG3DkpkcvZMqF70SPl3HDw==
=kPW3
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 21, 2004

From whatever@davidnicol.com

On Sat, 2004-08-21 at 02​:59, Aaron Sherman wrote​:

If you really feel that perlop needs [documentation of
coding conventions regarding no-ops] (is perlop
the right place for it?), then ...

"perlstyle" might be ripe for some addenda

--
david nicol
  "Someday, everything's going to be different
  when I paint my masterpiece."

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From rick@bort.ca

On Sat, Aug 21, 2004 at 07​:43​:03PM +0200, Tels wrote​:

On Saturday 21 August 2004 19​:34, Rick Delaney wrote​:

Anyway, aren't those taken care of by overloaded C<++>? If not, I think
that is a bug. The for loop is optimized to use C<++> so that this
would have some hope of finishing (someday)​:

 perl \-Mbignum \-le "for \(1 \.\. 78901234567899\) \{ print $\_; \}"

Overloaded C<..> wouldn't help there. Or here​:

 perl \-Mbignum \-le "@&#8203;x = \(1 \.\. 78901234567899\); for \(@&#8203;x\) \{ print $\_; \}"

No, ".." bypasses the "​:constant" stuff like this​:

te@&#8203;linux&#8203;:\~> 
perl \-Mbignum \-le 'print ref\(1\); for \(1\.\. 5\) \{ print "$\_ " \. ref\($\_\); \}'
Math&#8203;::BigInt
1
2
3
4
5

(Expected is 1 Math​::BigInt, 2 Math​::BigInt etc)

Yes, this could be a bug. The following patch makes that print

Math​::BigInt
1 Math​::BigInt
2 Math​::BigInt
3 Math​::BigInt
4 Math​::BigInt
5 Math​::BigInt

But this patch has nothing to do with C<..> as it doesn't touch
pp_range. This would still produce the old results​:

perl -Mbignum -le 'print ref(1); @​a = (1..5); for (@​a) { print "$_ " . ref($_); }'

The reason the patch helps is because foreach loops optimize

  for (1..5) { }

into (sort of)

  for (my $i = 1; $i <= 5; $i++) { }

so suitable overloaded '++' and '<=' (actually implemented using
overloaded '>').

te@&#8203;linux&#8203;:\~> perl \-Mbignum \-le 'my $a = 1234567890123456789; \\
for \($a \.\. $a\+5\) \{ print "$\_ " \. ref\($\_\); \}'
Range iterator outside integer range at \-e line 1\.

This now prints

1234567890123456789 Math​::BigInt
1234567890123456790 Math​::BigInt
1234567890123456791 Math​::BigInt
1234567890123456792 Math​::BigInt
1234567890123456793 Math​::BigInt
1234567890123456794 Math​::BigInt

Good for Math​::BigInt, but what about stringier objects? Some class may
want

  for ("a" .. "z") { }

to be optimized to

  for (my $s = "a"; $s le "z"; $s++) { }

Note that this class provides overloaded 'le', not '<=' and so the patch
would not cover this case and the author/users of this class are out of
luck. I can see no way to distinguish whether an inc operation is
supposed to be numeric or stringy. Maybe it's even a bug that overload
doesn't let you have both.

".." so far rather defeats the bignum package. And as long as _any_ code
contains a ".." or "..." operator somewhere, it will break when passed a
BigInt, e.g.​:

package Foo;
sub foo
  \{
      \# works
      my $a = shift;
      my $b = $a \+5;
  while \($a\+\+ \< $b\)  \{ \.\.\. \}
  \}
sub bar
  \{
      \# breaks with BigInt passed in
      my $a = shift;
      my $b = $a \+5;
  for \($a \.\. $b\) \{ \.\.\. \}
  \}

Thats not good, since the caller of foo() or bar() shouldn't need to care
how foo() or bar() work inside.

I agree with this from a philosophical view, but I'm not so sure from a
practical one. Do you get a lot of bug reports for failing bignum
ranges? In fact, I think I'd rather see

  @​a = (1 .. shift);

die with 'Range iterator outside integer range' than suck up all my swap
for a suitably large bigint. But I could be way off base since I never
use bigints at all.

--
Rick Delaney
rick@​bort.ca

Inline Patch
--- perl-current/pp_ctl.c	Sat Aug 14 18:54:20 2004
+++ perl-dev/pp_ctl.c	Sat Aug 21 22:41:15 2004
@@ -1808,7 +1808,10 @@
 	if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
 	    dPOPss;
 	    SV *right = (SV*)cx->blk_loop.iterary;
-	    if (RANGE_IS_NUMERIC(sv,right)) {
+	    if (SvAMAGIC(sv)) {
+		cx->blk_loop.iterlval = newSVsv(sv);
+	    }
+	    else if (RANGE_IS_NUMERIC(sv,right)) {
 		if ((SvOK(sv) && SvNV(sv) < IV_MIN) ||
 		    (SvOK(right) && SvNV(right) >= IV_MAX))
 		    DIE(aTHX_ "Range iterator outside integer range");
--- perl-current/pp_hot.c	Sat Jul 31 12:44:58 2004
+++ perl-dev/pp_hot.c	Sat Aug 21 22:34:33 2004
@@ -1855,7 +1855,17 @@
 	    register SV* cur = cx->blk_loop.iterlval;
 	    STRLEN maxlen = 0;
 	    char *max = SvOK((SV*)av) ? SvPV((SV*)av, maxlen) : "";
-	    if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
+	    if (SvAMAGIC(cur)) {
+		oldsv = *itersvp;
+		*itersvp = newSVsv(cur);
+		SvREFCNT_dec(oldsv);
+		if (SvTRUE(amagic_call(cur, (SV*)av, gt_amg,0)))
+		    RETPUSHNO;
+		else
+		    AMG_CALLun(cur, inc);
+		RETPUSHYES;
+	    }
+	    else if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
 		if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) {
 		    /* safe to reuse old SV */
 		    sv_setsv(*itersvp, cur);

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From @jidanni

Aaron> (is perlop the right place for it?),

Well, where better to look for something about no-op operator than on
the "op" page? -- or so one would think.

Aaron> then I would say something like​:

[Nice example deleted.]

Aaron> There is nothing particularly interesting about a constant 1

Also mention that they can also use 0, if they prefer a false return
value.

Aaron> I would not bother using C<1> here

Also if just reading perlop the user wouldn't know what was being
talked about.

Aaron> Dan, your original question seemed to be of the form​:
Aaron> How do I modify​:
Aaron> next if large_amount_of_work();
Aaron> so that it does nothing?

No. I am just miffed that mighty Perl does not have even one official word
about how to do a no-op, nowhere.

Aaron> Now, I know I might be being dense here, but can't you simply comment
Aaron> out the line?

Here in Nurd Labs we work with Makefiles, so often no comments allowed
for many a backslashed extra line. I wanted a way to deball a wad of
code without poking around to find its end to wrap a brace around, etc.
However never mind that. Mighty Perl's got a "goto" but not even
instructions how to do a no-op. So, Arron, mention 0 and add your
example to perlop. Thanks. P.S. maybe mention why 1 works but not 1.4,
-1 etc. or perhaps never mind that.

P.S.​: to those who are polluting my no-op bug with ".." "..." bugs​:
bug-off​:-) get your own bug.

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From whatever@davidnicol.com

On Sat, 2004-08-21 at 16​:20, Dan Jacobson wrote​:

No. I am just miffed that mighty Perl does not have even one official word
about how to do a no-op, nowhere.

I think perlsyn would benefit from having a noop mentioned
in the section on goto LABEL, because perl does not let you
label a label​:

[david@​plaza david]$ perl -wle 'goto fuzz; print 1; fuzz​: print 2'
2
[david@​plaza david]$ perl -wle 'goto fuzz; print 1; pre​: fuzz​: baz​:
print 2'
syntax error at -e line 1, near "pre​: fuzz​:"
Execution of -e aborted due to compilation errors.
[david@​plaza david]$ perl -wle 'goto fuzz; print 1; pre​: ;fuzz​: baz​:
print 2'
syntax error at -e line 1, near "fuzz​: baz​:"
Execution of -e aborted due to compilation errors.
[david@​plaza david]$ perl -wle 'goto fuzz; print 1; pre​: ;fuzz​: ;baz​:
print 2'
2
[david@​plaza david]$

you have to put a semicolon or something there.

Here's a patch.

Inline Patch
--- perlpod/perlsyn.pod	Mon Aug 18 15:12:12 2003
+++ perlhacking/perlsyn.pod	Sun Aug 22 00:53:21 2004
@@ -513,11 +513,14 @@
 =head2 Goto
 
 Although not for the faint of heart, Perl does support a C<goto>
 statement.  There are three forms: C<goto>-LABEL, C<goto>-EXPR, and
 C<goto>-&NAME.  A loop's LABEL is not actually a valid target for
-a C<goto>; it's just the name of the loop.
+a C<goto>; it's just the name of the loop. When you must create a
+goto target immediately before a labeled loop, or if you want to
+have more than one label referring to the same place, the labels
+can be separated with semicolons, which function as Perl's no-op.
 
 The C<goto>-LABEL form finds the statement labeled with LABEL and
resumes execution there\. It may not be used to go into any construct that requires initialization\, such as a subroutine or a C\ loop\. It also can't be used to go into a construct that is optimized away\. It

--
david nicol
  "Someday, everything's going to be different
  when I paint my masterpiece."

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From @ysth

On Sat, Aug 21, 2004 at 03​:59​:41AM -0400, Aaron Sherman <ajs@​ajs.com> wrote​:

It's a bit hard to make out. If you really feel that perlop needs such a
thing (is perlop the right place for it?), then I would say something like​:
...
There is nothing particularly interesting about a constant 1 that
makes it more attractive for such usage over any other number, but

Yes, there is; 0 and 1 are exempt from the "Useless use of a constant
in void context" warning.

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From @ysth

On Fri, Aug 20, 2004 at 08​:38​:35PM -0500, david nicol <whatever@​davidnicol.com> wrote​:

On Fri, 2004-08-20 at 07​:21, Nicholas Clark wrote​:

I made a patch to implement ... (well, at least part of its perl6
functionality) and sent it to p5p some time ago. IIRC it got mostly
Warnocked. However, these days it seems more appropriate for the aim of
5.10, so I might try to dig it out.

Nicholas Clark

Is the current behavior of threedots deprecated?

In general, perl's tokenizer has separate "expecting an operator" and
"expecting a term" states. The existing ... operator wouldn't be
much affected by a patch that allowed ... as a term.

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Sunday 22 August 2004 05​:21, Rick Delaney wrote​:

On Sat, Aug 21, 2004 at 07​:43​:03PM +0200, Tels wrote​:

On Saturday 21 August 2004 19​:34, Rick Delaney wrote​:

Anyway, aren't those taken care of by overloaded C<++>? If not, I
think that is a bug. The for loop is optimized to use C<++> so that
this would have some hope of finishing (someday)​:

 perl \-Mbignum \-le "for \(1 \.\. 78901234567899\) \{ print $\_; \}"

Overloaded C<..> wouldn't help there. Or here​:

 perl \-Mbignum \-le "@&#8203;x = \(1 \.\. 78901234567899\); for \(@&#8203;x\) \{ print $\_;

}"

No, ".." bypasses the "​:constant" stuff like this​:

te@&#8203;linux&#8203;:\~>
perl \-Mbignum \-le 'print ref\(1\); for \(1\.\. 5\) \{ print "$\_ " \. ref\($\_\);

}' Math​::BigInt
1
2
3
4
5

(Expected is 1 Math​::BigInt, 2 Math​::BigInt etc)

Yes, this could be a bug. The following patch makes that print

You are my hero :-)

But this patch has nothing to do with C<..> as it doesn't touch
pp_range. This would still produce the old results​:

perl -Mbignum -le 'print ref(1); @​a = (1..5); for (@​a) { print "$_ " .
ref($_); }'

The reason the patch helps is because foreach loops optimize

for \(1\.\.5\) \{ \}

into (sort of)

for \(my $i = 1; $i \<= 5; $i\+\+\) \{ \}

so suitable overloaded '++' and '<=' (actually implemented using
overloaded '>').

Ah cool. Didn't know this.

te@&#8203;linux&#8203;:\~> perl \-Mbignum \-le 'my $a = 1234567890123456789; \\
for \($a \.\. $a\+5\) \{ print "$\_ " \. ref\($\_\); \}'
Range iterator outside integer range at \-e line 1\.

This now prints

1234567890123456789 Math​::BigInt
1234567890123456790 Math​::BigInt
1234567890123456791 Math​::BigInt
1234567890123456792 Math​::BigInt
1234567890123456793 Math​::BigInt
1234567890123456794 Math​::BigInt

Good for Math​::BigInt, but what about stringier objects? Some class may
want

for \("a" \.\. "z"\) \{ \}

to be optimized to

for \(my $s = "a"; $s le "z"; $s\+\+\) \{ \}

Hm, Math​::String would be such an object. See below.

Let's do the for("a" .. "z") class aside and look at objects for the range.
The reason that (1..5) has objects under bignum is because it turns
constants like 1 and 5 into objects. I 'think' it would be possible to do
this for strings but I am unaware of such an object.

However, not only does the object need to accept strings as input, it also
needs to do simple math with them, e.g. incrementing and comparing to a
right range. E.g. it needs to define strings as a series in integer space.
(the .. operator is currently all about integer series or the autmagically
inreement ++ on strings - which I never liked for it's seemingly random
rules what to increment how).

Math​::String is such an object, although it works a bit different under the
hood. It defines '' as the number 0, 'a' as the number 1, 'b' as 2 and son
on to 'z' as 26. (default is a...z, but that works with any simple charset,
not only a..z and also with more complicated charsets). Which means
Math​::String simple provides simple a one-to-one mapping between a series
of integers (starting with 0) and another series of strings. By defininy
math on the underlying integer series, you can do math with Strings (its a
bit like magic :)

So​:

  use Math​::String;
  $a = Math​::String->new('a');
  $z = Math​::String->new('ad');
  for ($a..$z) { print ref($_), " $_\n"; }

I think after your patch that should print

  Math​::String a
  Math​::String b
  ...
  Math​::String z
  Math​::String aa
  Math​::String ab
  Math​::String ac
  Math​::String ad

which is way cool :)

Note that this class provides overloaded 'le', not '<=' and so the patch
would not cover this case and the author/users of this class are out of
luck. I can see no way to distinguish whether an inc operation is
supposed to be numeric or stringy. Maybe it's even a bug that overload
doesn't let you have both.

OTOH, @​a = ('a' .. 'z') uses automagically ++ as operation (the 1..5) case
could be viewed as special case). Maybe that should simple be added to
overload.pm, so that classes can define their behaviour for this (distinc,
IMO) operation. A fallback would then be for numerical ++ if the class
doesn't provide magical increment. I am not sure if a distinct compare
operation is also need or if it would work out-of-the-box. The first test
could be writing a class which objects behaves exactly like '1' or 'a' in
the .. cases. Note that that would be a bit different from Math​::String,
since '9a' will wrap to '9b', but I cannot understand what Perl does here​:

te@​linux​:~> perl -wle 'my $c = "a9a"; $c .= ""; $c++; print $c'
1
te@​linux​:~> perl -wle 'my $c = "9a"; $c .= ""; $c++; print $c'
10

huh?

In addition​:

te@​linux​:~> perl -wle 'for ("a" .. "b") { print $_ }'
a
b
te@​linux​:~> perl -wle 'for ("9a" .. "9b") { print $_ }'
9a
te@​linux​:~> perl -wle 'for ("aa" .. "1ac") { print $_ }'
[produces aa .. zzz for some reason]
te@​linux​:~> perl -wle 'for ("aa" .. "ad") { print $_ }'

As I said, the rules for /[^a-z]/ strings are non-obvious to me. (I once
said that Math​::String is a '++' replacement that simple behaves sane :)

For the "simple" case of a charset of "a".."z" Math​::String should behave
just like the automagical '++'.

".." so far rather defeats the bignum package. And as long as _any_
code contains a ".." or "..." operator somewhere, it will break when
passed a BigInt, e.g.​:

package Foo;
sub foo
  \{
      \# works
      my $a = shift;
      my $b = $a \+5;
  while \($a\+\+ \< $b\)  \{ \.\.\. \}
  \}
sub bar
  \{
      \# breaks with BigInt passed in
      my $a = shift;
      my $b = $a \+5;
  for \($a \.\. $b\) \{ \.\.\. \}
  \}

Thats not good, since the caller of foo() or bar() shouldn't need to
care how foo() or bar() work inside.

I agree with this from a philosophical view, but I'm not so sure from a
practical one. Do you get a lot of bug reports for failing bignum
ranges? In fact, I think I'd rather see

@​a = (1 .. shift);

die with 'Range iterator outside integer range' than suck up all my swap
for a suitably large bigint. But I could be way off base since I never
use bigints at all.

I think it would die anyway, because arrays can currently not have more than
2**32 elements (2**64 on 64bit platforms?). However, for small arguments
there would still be difference on whether the array contains objects, or
integers​:

te@​linux​:~> cat array.pl
#!/usr/bin/perl -w

my_sqrt(5);

sub my_sqrt
  {
  my @​a = (1..$_[0]);

  for (@​a) { print sqrt($_),"\n"; }

  for ($i = 1; $i < $_[0]; $i++) { print sqrt($i),"\n"; }
  }
te@​linux​:~> perl -Mbignum array.pl
1
1.4142135623731
1.73205080756888
2
2.23606797749979
1
1.41421356237309504880168872420969807857
1.732050807568877293527446341505872366943
2

Of course, I have no idea if this is really important. Grepping core modules
for usage of '..' in both forms?

There are very little users of bignum and as long as they don't post to a
newsgroup, or email me, I will not see their complaints :/

In any event, I mixed up the old bugs​:

I thought to remember a problem with Benchmark.pm similiar to this one​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-08/msg01059.html

(btw, the speed difference is now *cough*only*cough* a factor of 400 for
that benchmark mention in that message).

I remember that simple putting "use bignum;" atop broke Benchmark, because
the parameters passed to it were suddenly BigInts, instead of integers and
I _thought_ ".." was somehow involved inside Benchmark.pm.

However, it was/is ref() that creates the problem​:

te@​linux​:~> cat bench.pl
#!/usr/bin/perl -w

use Benchmark qw/cmpthese/;

my $a = $b = 0;

cmpthese ( -2,
  {
  'add' => sub { $a = $b + 12345; },
  'sub' => sub { $a = $b - 12345; },
  } );

te@​linux​:~> perl bench.pl
  Rate sub add
sub 7756676/s -- -15%
add 9112423/s 17% --
te@​linux​:~> perl -Mbignum bench.pl
Can't use string ("-") as an ARRAY ref while "strict refs" in use
at /usr/lib/perl5/5.8.3/Benchmark.pm line 880.
te@​linux​:~>

# line 880-882 of Benchmark​:
  if( ref $_[0] ) {
  ($results, $style) = @​_;
  }

Back then I wanted to fix Benchmark (testing for ref() eq 'HASH' (or ARRAY
dunno what it expects)). I forgot the exact reason why that proposal was
shot down. I still think at least the core modules should work with bignum
out of the box.

OTOH, nobody has probably tried to feed bignums to each core module's
function and see what breaks. Hm, running the testsuite under -Mbignum?

Best wishes,

Tels

PS​: Funny, the fix for the bug introcuded in
http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-08/msg01017.html
was slightly wrong, it should have been $src >= $xlen and I fixed this like
oh, only a few weeks ago :)
PPS​: Sorry for rambling on. :)

- --
Signed on Sun Aug 22 10​:39​:11 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

"Call me Justin, Justin Case."

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQShq2HcLPEOTuEwVAQFSFQf+JbWg+aP/9vcxNIOQPDOuvY+vGO+k80Yk
01iuxriJGDGQBlr0BUHXnpjqd5F1yn/C6NYIiiQIaY2y4ljaDlrP9D2f6bgscRtU
IA+OVxDZItSUSvQSMIok9Ua1yahs+05dvmmILTNCRZaTOoIELc2QnT2ZvmkhMays
35K3gLaiasjZbh+nEdXw6p+SrgIFukvCD4sMU4GHgC/YVJWZWpJn3ryfQatdP1ML
X+teog1X+Gm+yrxipJapX6dSyTTKxeOjiggsxZh2XfoSBr3rg8TkIIC3R4VpinFR
aNmgBXhoTypYgxh7A1p265JG/AOyj7jJEnaIwIssWEtSP7FDm1RBvw==
=BxsS
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From @ysth

On Sun, Aug 22, 2004 at 11​:43​:52AM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

I cannot understand what Perl does here​:

te@​linux​:~> perl -wle 'my $c = "a9a"; $c .= ""; $c++; print $c'
1
te@​linux​:~> perl -wle 'my $c = "9a"; $c .= ""; $c++; print $c'
10

huh?

Magical string increment only applies to /^[a-zA-Z]*[0-9]*\z/ strings.
If there are digits preceeding letters, it doesn't, so "a9a" and "9a"
are just treated as numbers (0 and 9, respectively). I don't see why
this case is exempt from a "Argument "%s" isn't numeric" warning, though.

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From perl_dummy@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Sunday 22 August 2004 12​:10, Yitzchak Scott-Thoennes wrote​:

On Sun, Aug 22, 2004 at 11​:43​:52AM +0200, Tels <perl_dummy@​bloodgate.com>
wrote​:

I cannot understand what Perl does here​:

te@​linux​:~> perl -wle 'my $c = "a9a"; $c .= ""; $c++; print $c'
1
te@​linux​:~> perl -wle 'my $c = "9a"; $c .= ""; $c++; print $c'
10

huh?

Magical string increment only applies to /^[a-zA-Z]*[0-9]*\z/ strings.

Aaah! I wrongly remembered it the other way round..

If there are digits preceeding letters, it doesn't, so "a9a" and "9a"
are just treated as numbers (0 and 9, respectively). I don't see why
this case is exempt from a "Argument "%s" isn't numeric" warning, though.

Me neither :)

Interesting is also if one of them is not the expected format​:

te@​linux​:~> perl -wle 'for ("a9" .. "az") { print $_ }'

This goes to "z9" on my system. Presumable because "aa0" gt "az"?

te@​linux​:~> perl -wle 'print "z9" lt "z9" ? "yes" : "no"'
no
te@​linux​:~> perl -wle 'print "z9" gt "z9" ? "yes" : "no"'
no

Okay.

te@​linux​:~> perl -wle 'print "z8" gt "z9" ? "yes" : "no"'
no
te@​linux​:~> perl -wle 'print "z8" lt "z9" ? "yes" : "no"'
yes

Okay.

te@​linux​:~> perl -wle 'print "aa0" gt "z9" ? "yes" : "no"'
no
te@​linux​:~> perl -wle 'print "aa0" lt "z9" ? "yes" : "no"'
yes
te@​linux​:~> perl -wle '$a = "z9"; print ++$a;'
aa0

perl -wle '$a = "z9"; $b = $a; $b++; print $b gt $a ? "yes" : "no"'
no
perl -wle '$a = "z9"; $b = $a; $b++; print $b > $a ? "yes" : "no"'
Argument "z9" isn't numeric in numeric gt (>) at -e line 1.
Argument "aa0" isn't numeric in numeric gt (>) at -e line 1.
no

As I said, automagical ++ is simple insane...

Cheers,

Tels

- --
Signed on Sun Aug 22 12​:07​:37 2004 with key 0x93B84C15.
Visit my photo gallery at http​://bloodgate.com/photos/
PGP key on http​://bloodgate.com/tels.asc or per email.

This email violates U.S. patent #6,756,999 <http​://tinyurl.com/2vuqm>​:

  [ [ Konsoles* ] [ Mozilla ] [ KMail ]]

-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.2.4 (GNU/Linux)
Comment​: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQSh0zXcLPEOTuEwVAQHIuwf+Mzjn5suZiCoLwU8fM+CqH0JmT2N4bicP
CYqNJzi0tsHxbe4zSlMG78dUkBdLkd1irpd4EPguoK83i5xirzBA3xu4wyUqQzgI
35NP7h1iKDbuDdQkxAhfcn5W8zaI7Q8Nxy777Rgdy7xyxkOy3Cg8x9pnujV806Tk
jDfuOwUCtEGkzpcH5Y3gO0/uWu+5FLIQnPjqfG5shE1WpTf+cIrGIVx+c9whckR9
EubyAwyV0xp3eNG8WTCljIyAwa6FwATPVJgxpRAOSny8lmhPBbo4VC4+R42YXAEI
tA+Pn6QKfig4ORISMiSs1DIWIMqU5CRNUIyf/kgbMJSDltNYFD3TOQ==
=bO3y
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From @ysth

On Sun, Aug 22, 2004 at 12​:26​:14PM +0200, Tels <perl_dummy@​bloodgate.com> wrote​:

-----BEGIN PGP SIGNED MESSAGE-----

Moin,

On Sunday 22 August 2004 12​:10, Yitzchak Scott-Thoennes wrote​:

On Sun, Aug 22, 2004 at 11​:43​:52AM +0200, Tels <perl_dummy@​bloodgate.com>
wrote​:

I cannot understand what Perl does here​:

te@​linux​:~> perl -wle 'my $c = "a9a"; $c .= ""; $c++; print $c'
1
te@​linux​:~> perl -wle 'my $c = "9a"; $c .= ""; $c++; print $c'
10

huh?

Magical string increment only applies to /^[a-zA-Z]*[0-9]*\z/ strings.

Aaah! I wrongly remembered it the other way round..

If there are digits preceeding letters, it doesn't, so "a9a" and "9a"
are just treated as numbers (0 and 9, respectively). I don't see why
this case is exempt from a "Argument "%s" isn't numeric" warning, though.

Me neither :)

Interesting is also if one of them is not the expected format​:

te@​linux​:~> perl -wle 'for ("a9" .. "az") { print $_ }'

This goes to "z9" on my system. Presumable because "aa0" gt "az"?

Not exactly. If it never reaches the range-end, it stops when it exceeds
it in length. This stuff is documented in perlop.

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2004

From rick@bort.ca

On Sun, Aug 22, 2004 at 04​:41​:29PM +0200, Tels wrote​:

Rick, your patch did not apply cleanly to blead, so I did it manually. I
also added a test to overload.t (it could go into range.t, but it needs one
object with overloading, and overload.t already got all we need).

Hmm, it applies for me. Are you sync'ed?

Unfortunately, the test fails​:

not ok 485​: 'Oscalar1Oscalar3' ne 'Oscalar1Oscalar2Oscalar3Oscalar4'
not ok 486​: 'Oscalar1Oscalar3' ne 'Oscalar1Oscalar2Oscalar3Oscalar4'

If you look at line 150 you'll see

eval q[package Oscalar; use overload ('++' => sub { $ {$_[0]} += 2; $_[0] } ) ];
  ^^^^

Also, I don't see that Oscalar has overloaded '>', but that's ok because
that case needs to be tested too. It's probably better to create a new
package for these tests so they can be insulated from the other tests.

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 2004

From @jidanni

david> I think perlsyn would benefit from having a noop mentioned

OK, but perlOP too, because that's the first place one would look for
a noOP.

Also, fellas, please move all other new non-noop threads off this bug
onto other bugs else when power is restored after the typhoon here my
modem will have to download so many messages.

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2004

From whatever@davidnicol.com

Dan​:

How exactly did you get into the position of looking for a noop?

I was a little surprised to find that the technique of separating labels
with semicolons was not documented where I looked for it. I guess I
hit on it without difficulty when I needed it, through experimentation.

There isn't an explicit no-op operator in perl.

Why do you think one is needed? Nobody else seems
to miss it. C doesn't have one either. Asssembler has them for filling
out page sizes in code generation and providing explicit targets for
jumps. I must be missing something. What is it?

On Mon, 2004-08-23 at 12​:18, Dan Jacobson wrote​:

david> I think perlsyn might benefit from having a noop mentioned

OK, but perlOP too, because that's the first place one would look for
a noOP.

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2004

From whatever@davidnicol.com

Okay here is what Rafael said, in the form of a patch to perlop. Had
this been in there, Dan's grepping would have produced something useful.

We can list other things in this new section as they appear to be
documented.

Maybe the section should be somewhere other than tacked at the end. But
where?

Inline Patch
--- perl-current/pod/perlop.pod	Wed Jun 30 07:36:41 2004
+++ perl-current-docpatch/pod/perlop.pod	Thu Aug 26 02:00:31 2004
@@ -2197,5 +2197,10 @@
 	Math::GMP		another one using an external C library
 
 Choose wisely.
 
+=head2 Pseudo-operators
+
+C<1> and C<0>, the cheap no-ops,  are special cased in the parser
+to avoid generating warnings on things like C<1 while foo()>.
+
 =cut

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2004

From @jidanni

[I get the messages thru perlbug-followup apparently, so no need to CC me.]

david> How exactly did you get into the position of looking for a noop?

Often I use perl -e in Makefiles, emacs file local variables, and other
situations where newlines don't count so comments don't end, so can't
be used. /bin/sh has "​:".

I want to replace
bla if ....
with
noop if ....
i.e., I only want to tamper with that one spot, not disturb other
parts of the file.

It turns out 0 and 1 is what I want.

So the big and only problem is they weren't documented.
If they were documented I would have found them.
And of course I looked for them using the words no-op and noop.
And of course I looked for them on the perlOP page. Also with perldoc
-q, -f.

Therefore document no-op or noop (0,1), please.

david> There isn't an explicit no-op operator in perl.
david> Why do you think one is needed? Nobody else seems
david> to miss it. C doesn't have one either.

well C doesn't fit in Makefiles

Anyway, perl already has no-op's, 0 and 1, just doesn't document them.

@p5pRT
Copy link
Author

p5pRT commented Aug 27, 2004

From @ysth

On Fri, Aug 27, 2004 at 05​:52​:03AM +0800, Dan Jacobson <jidanni@​jidanni.org> wrote​:

Often I use perl -e in Makefiles, emacs file local variables, and other
situations where newlines don't count so comments don't end, so can't
be used. /bin/sh has "​:".

You can use comments by breaking up your code into multiple -e switches
(each of which represents a "line").

For instance, to comment out the first statement in​:
$ perl -we'print "win!\n" if $^O =~ /win/i; print "OS is $^O\n"'
win!
OS is cygwin

say​:
$ perl -we'# print "win!\n" if $^O =~ /win/i; ' -e' print "OS is $^O\n"'
OS is cygwin

(though the ' -e' break can come at arbitrary points, not just
statement boundaries.)

@p5pRT
Copy link
Author

p5pRT commented Aug 28, 2004

From whatever@davidnicol.com

After some meditation I think it makes sense right after "Constant Folding."

Inline Patch
--- perl-current/pod/perlop.pod	Wed Jun 30 07:36:41 2004
+++ perl-current-docpatch/pod/perlop.pod	Fri Aug 27 21:07:42 2004
@@ -2057,10 +2057,15 @@
     }
 
 the compiler will precompute the number which that expression
 represents so that the interpreter won't have to.
 
+=head2 Pseudo-operators
+
+C<1> and C<0>, the cheap no-ops,  are special cased in the parser
+to avoid generating warnings on things like C<1 while foo()>.
+
 =head2 Bitwise String Operators
 
 Bitstrings of any size may be manipulated by the bitwise operators
 (C<~ | & ^>).
 

@p5pRT
Copy link
Author

p5pRT commented Aug 29, 2004

From @jidanni

david> +C<1> and C<0>, the cheap no-ops, are special cased in the parser
  ^[extra blank.]
OK, thanks. Folks will now be able to find no-op in the documentation.

@p5pRT
Copy link
Author

p5pRT commented Aug 30, 2004

From @tamias

On Fri, Aug 27, 2004 at 09​:13​:42PM -0500, david nicol wrote​:

--- perl-current/pod/perlop.pod Wed Jun 30 07​:36​:41 2004
+++ perl-current-docpatch/pod/perlop.pod Fri Aug 27 21​:07​:42 2004
@​@​ -2057,10 +2057,15 @​@​
}

the compiler will precompute the number which that expression
represents so that the interpreter won't have to.

+=head2 Pseudo-operators
+
+C<1> and C<0>, the cheap no-ops, are special cased in the parser
+to avoid generating warnings on things like C<1 while foo()>.
+

Nit​: special-cased

Ronald

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2004

From @iabyn

On Fri, Aug 27, 2004 at 09​:13​:42PM -0500, david nicol wrote​:

After some meditation I think it makes sense right after "Constant Folding."

--- perl-current/pod/perlop.pod Wed Jun 30 07​:36​:41 2004
+++ perl-current-docpatch/pod/perlop.pod Fri Aug 27 21​:07​:42 2004
@​@​ -2057,10 +2057,15 @​@​
}

the compiler will precompute the number which that expression
represents so that the interpreter won't have to.

+=head2 Pseudo-operators
+
+C<1> and C<0>, the cheap no-ops, are special cased in the parser
+to avoid generating warnings on things like C<1 while foo()>.
+

I've accepted be basic idea of the patch, but changed the wording.

Dave.

--
O Unicef Clearasil!
Gibberish and Drivel!
  - "Bored of the Rings"

Change 23250 by davem@​davem-percy on 2004/09/01 20​:46​:13

  From​: david nicol <whatever@​davidnicol.com>
  Subject​: [perl #31228] no no-op
  Message-Id​: 1093659222.1436.70.camel@​plaza.davidnicol.com>
  Date​: 27 Aug 2004 21​:13​:42 -0500
 
  Document that 0 and 1 can (sort of) be used as no-ops.

Affected files ...

... //depot/perl/pod/perlop.pod#121 edit

Differences ...

==== //depot/perl/pod/perlop.pod#121 (text) ====

@​@​ -2059,6 +2059,14 @​@​
the compiler will precompute the number which that expression
represents so that the interpreter won't have to.

+=head2 No-ops
+
+Perl doesn't officially have a no-op operator, but the bare constants
+C<0> and C<1> are special-cased to not produce a warning in a void
+context, so you can for example safely do
+
+ 1 while foo();
+
=head2 Bitwise String Operators

Bitstrings of any size may be manipulated by the bitwise operators

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant