[33165] in Perl-Users-Digest
Perl-Users Digest, Issue: 4444 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Jun 2 18:09:20 2015
Date: Tue, 2 Jun 2015 15:09:03 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 2 Jun 2015 Volume: 11 Number: 4444
Today's topics:
Re: Comparing Lists <see.my.sig@for.my.address>
Re: Comparing Lists <ben.usenet@bsb.me.uk>
Re: Comparing Lists <see.my.sig@for.my.address>
Re: Comparing Lists <rweikusat@mobileactivedefense.com>
Re: Comparing Lists <rweikusat@mobileactivedefense.com>
Re: Puzzling Substitution Failure <JimSGibson@gmail.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Mon, 01 Jun 2015 07:10:05 -0700
From: Robbie Hatley <see.my.sig@for.my.address>
Subject: Re: Comparing Lists
Message-Id: <vcGdnZP-5OYw-vHInZ2dnUVZ572dnZ2d@giganews.com>
At 3:22PM on the morning of 5/28/2015, Rainer Weikusat wrote
(regarding the habit of some C, C++, and Perl programmers to write
equality tests as '37 == $blue_cars' instead of '$blue_cars == 37):
> Considering that this has been handed down as "r3@lly ph@t 1ns1d3rz
> tr1ck" among generations of people who felt the desire to put their
> refusal to learn this in writing, it's not puzzling at all, just
> annoying to anyone else. Which is IMHO the whole point of it, especially
> considering that it doesn't work as lvalues also need to be compared
> with other lvalues.
I'll allow as how it can seem "annoying", especially in light of its
violation of natural language patterns.
However, I think that in most cases, annoyance is not the purpose.
The purpose is to avoid hard-to-troubleshoot run-time errors by
replacing them with easy-to-troubleshoot compile-time errors.
For example, the following will cause any C++ compiler to abort
compilation:
if (37 = blue_cars) {std::cout << "Hi!" << std::endl;} // C++ ERROR
Now, it's true that that trick won't work for LVALUES, as in this
(probably buggy) Perl code:
say "Hi!" if $fred = $bob; # VALID Perl code, but probably wrong.
However, saying that the trick is pointless because it won't work
in all cases is like saying that people shouldn't use seatbelts
and airbags because "sometimes they fail". You'd need a better
reason than that to eschew them, I think. You'd need to show
they cause more problems than they solve.
So I think it boils down to this question: "which is more annoying:
puzzling run-time errors, or 'backwards' equality tests?" I'll go
for the backwards tests. I don't mind doing things backwards.
--
Cheers,
Robbie Hatley
Midway City, CA, USA
perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"'
http://www.well.com/user/lonewolf/
https://www.facebook.com/robbie.hatley
------------------------------
Date: Mon, 01 Jun 2015 15:28:56 +0100
From: Ben Bacarisse <ben.usenet@bsb.me.uk>
Subject: Re: Comparing Lists
Message-Id: <87twur4i53.fsf@bsb.me.uk>
Robbie Hatley <see.my.sig@for.my.address> writes:
> At 3:22PM on the morning of 5/28/2015, Rainer Weikusat wrote
> (regarding the habit of some C, C++, and Perl programmers to write
> equality tests as '37 == $blue_cars' instead of '$blue_cars == 37):
>
>> Considering that this has been handed down as "r3@lly ph@t 1ns1d3rz
>> tr1ck" among generations of people who felt the desire to put their
>> refusal to learn this in writing, it's not puzzling at all, just
>> annoying to anyone else. Which is IMHO the whole point of it, especially
>> considering that it doesn't work as lvalues also need to be compared
>> with other lvalues.
>
> I'll allow as how it can seem "annoying", especially in light of its
> violation of natural language patterns.
>
> However, I think that in most cases, annoyance is not the purpose.
> The purpose is to avoid hard-to-troubleshoot run-time errors by
> replacing them with easy-to-troubleshoot compile-time errors.
In my experience these are not hard to troubleshoot errors. They show
up immediately on testing if not before (see below).
> For example, the following will cause any C++ compiler to abort
> compilation:
>
> if (37 = blue_cars) {std::cout << "Hi!" << std::endl;} // C++ ERROR
Flip the order and you can get a warning about this from modern C and
C++ compilers. Perl will also warn about such constructs (if asked). I tink
<snip>
--
Ben.
------------------------------
Date: Mon, 01 Jun 2015 07:40:32 -0700
From: Robbie Hatley <see.my.sig@for.my.address>
Subject: Re: Comparing Lists
Message-Id: <pe-dnQB9DORT8_HInZ2dnUVZ57ydnZ2d@giganews.com>
On 5/29/2015 5:50 AM, Rainer Weikusat wrote:
> join '', map {chr} 48,38,178,117,142,102,207,17,166,217,0,170,0,98,206,108
>
> can also be expressed as
>
> pack('C*', 48,38,178,117,142,102,207,17,166,217,0,170,0,98,206,108)
I think I saw "pack" in the the list of "functions" in the Camel book
but skipped over it, not appreciating the value of "packing" things.
But your "pack" code does look simpler and more direct than join/map/chr.
And in this case I wouldn't need to use "unpack" either, as I'm comparing
fixed patterns to a $buffer containing the first 50 bytes of whatever
file I'm currently looking at.
> One of the nice things about perl is that it can run arbitrary Perl
> code while compiling so the pack('C*', ...) can also be used like this
> use constant SIGNATURE => pack('C*', ....);
Interesting, but really just moves the signature definitions up to the
top of the file instead of down in the "set_extension" subroutine where
they're being used. I prefer having them spelled out right inside the
elsifs's where the extensions are being set. This script has quite a
few different extensions in it (all of them the types of files you
find in browser caches with no file name extensions to tell you
what kind of files they are). Just a small sample (some of them now
using your "pack" idea):
# ====== AVI ======= :
elsif ("AVI" eq substr($buffer, 8, 3))
{
$new_suffix = '.avi';
}
# ====== FLAC ======= :
elsif ( 'fLaC' eq substr($buffer,0,4) )
{
$new_suffix = '.flac';
}
# ======= FLV ======= :
elsif ('FLV' eq substr($buffer,0,3) )
{
$new_suffix = '.flv';
}
# ====== GIF ======= :
elsif ( 'GIF' eq substr($buffer,0,3) )
{
$new_suffix = '.gif';
}
# ====== JPG ======= :
elsif ( pack('C3',255,216,255) eq substr($buffer,0,3) )
{
$new_suffix = '.jpg';
}
# ======= MP4 ======= :
elsif ( 'ftypmp4' eq substr($buffer,4,7) )
{
$new_suffix = '.mp4';
}
# ====== PDF ======= :
elsif ( 'PDF' eq substr($buffer,1,3) )
{
$new_suffix = '.pdf';
}
# ====== PNG ======= :
elsif ( 'PNG' eq substr($buffer,1,3) )
{
$new_suffix = '.png';
}
# ====== RAR ======= :
elsif ( 'Rar' eq substr($buffer,0,3) )
{
$new_suffix = '.rar';
}
# ====== WMA ======= :
elsif
(
pack('C[16]', 48, 38, 178, 117, 142, 102, 207, 17,
166, 217, 0, 170, 0, 98, 206, 108)
eq substr($buffer, 0, 16)
)
{
$new_suffix = '.wma';
}
# ====== DEFAULT ======= :
else
{
$new_suffix = '.unk';
}
--
Cheers,
Robbie Hatley
Midway City, CA, USA
perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"'
http://www.well.com/user/lonewolf/
https://www.facebook.com/robbie.hatley
------------------------------
Date: Mon, 01 Jun 2015 16:14:39 +0100
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Comparing Lists
Message-Id: <87siab795s.fsf@doppelsaurus.mobileactivedefense.com>
Robbie Hatley <see.my.sig@for.my.address> writes:
> At 3:22PM on the morning of 5/28/2015, Rainer Weikusat wrote
> (regarding the habit of some C, C++, and Perl programmers to write
> equality tests as '37 == $blue_cars' instead of '$blue_cars == 37):
>
>> Considering that this has been handed down as "r3@lly ph@t 1ns1d3rz
>> tr1ck" among generations of people who felt the desire to put their
>> refusal to learn this in writing, it's not puzzling at all, just
>> annoying to anyone else. Which is IMHO the whole point of it, especially
>> considering that it doesn't work as lvalues also need to be compared
>> with other lvalues.
>
> I'll allow as how it can seem "annoying", especially in light of its
> violation of natural language patterns.
>
> However, I think that in most cases, annoyance is not the purpose.
> The purpose is to avoid hard-to-troubleshoot run-time errors by
> replacing them with easy-to-troubleshoot compile-time errors.
>
> For example, the following will cause any C++ compiler to abort
> compilation:
>
> if (37 = blue_cars) {std::cout << "Hi!" << std::endl;} // C++ ERROR
This sticks out so plainly as obviously wrong that it ought to cause
someone else to 'abort compilation' before ever starting it. = is an
operator symbol without any natural meaning and in the context of a
C-like language, it means 'assignment'. This may have been a bad idea,
at least some people are seriously convinced of that (usually called
Niklaus or Wirth), but the corresponding descision was made almost
half a century ago: This discussion is long over and the people whose
opinion differed didn't prevail. That's a fact of life. Event elementary
school pupils are ruthlessly expected to learn much more complicated
things and considering this, the argument seem pretty unreal to me, not
really distinguishable from - say - arguing about how many angels can
dance on the head of a pin, and just about as useful.
> Now, it's true that that trick won't work for LVALUES, as in this
> (probably buggy) Perl code:
>
> say "Hi!" if $fred = $bob; # VALID Perl code, but probably wrong.
Here's a more interesting one:
say "Tasty!" if "bread" == $foodstuff;
This is almost certainly wrong as it converts the value of $foodstuff to a
number and compares it with 0.
> However, saying that the trick is pointless because it won't work
> in all cases is like saying that people shouldn't use seatbelts
> and airbags because "sometimes they fail".
I didn't write anything about 'seatbelts and airbags', not the least
because I know too little about this topic to have an informed
opinion. But picking up your example nevertheless: Assuming someone sits
on an ordinary airoplane seat, seatbelt fastenend, and seat and someone
are than dropped out of a plane bomb bay at an altitude of 10,000 feet,
that someone is going to be killed regardless of the seatbelt. Likewise,
there's no reodering of arguments to comparisons which will cause a
compiler to flag an erroneous assignment when a comparison of two
l-values was intended. The 'failure rate' is 100%, thus, everyone
programming who isn't (somehow) prevented/ prohibited from comparing
l-lvalues must be capable of handling the situation.
[...]
> So I think it boils down to this question: "which is more annoying:
> puzzling run-time errors, or 'backwards' equality tests?" I'll go
> for the backwards tests. I don't mind doing things backwards.
The runtime errors are transient, the intentionally confusing text
forever.
------------------------------
Date: Mon, 01 Jun 2015 21:19:17 +0100
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Comparing Lists
Message-Id: <87h9qr6v22.fsf@doppelsaurus.mobileactivedefense.com>
Robbie Hatley <see.my.sig@for.my.address> writes:
> On 5/29/2015 5:50 AM, Rainer Weikusat wrote:
[...]
>> One of the nice things about perl is that it can run arbitrary Perl
>> code while compiling so the pack('C*', ...) can also be used like this
>> use constant SIGNATURE => pack('C*', ....);
>
> Interesting, but really just moves the signature definitions up to the
> top of the file instead of down in the "set_extension" subroutine where
> they're being used.
[...]
> elsif ("AVI" eq substr($buffer, 8, 3))
> {
> $new_suffix = '.avi';
> }
[10 repetitions of the same code working with different data]
> # ====== DEFAULT ======= :
> else
> {
> $new_suffix = '.unk';
> }
One doesn't have to stop with moving the signatures out of the matching
code, all of the useful data can be collected in a 'signature data
structure' and the redundant data can be dropped, leading to something
like
---------
use constant S_SIG => 0;
use constant S_OFS => 1;
use constant S_EXT => 2;
my @sigs = (
['AVI', 8, 'avi'],
['fLaC', 0, 'flac'],
['FLV', 0, 'flv'],
['GIF', 0, 'gif'],
['ftypmp4', 4, 'mp4'],
['PDF', 1, 'pdf'],
['PNG', 1, 'png'],
['Rar', 0, 'rar' ],
[pack('C*', 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108),
0, 'wma'],
[pack('C*', 255, 216, 255),
0, 'jpg']);
sub guess_ext
{
for (@sigs) {
if (substr($_[0], $_->[S_OFS], length($_->[S_SIG])) eq $_->[S_SIG]) {
return '.'.$_->[S_EXT];
}
}
return '.wtf ';
}
---------
[purposely somewhat more verbose than I'd usually write it]
pack('C*', ...)
means 'pack everything which is available' --- it's not only that
computers are better at counting than humans but this also means the
input list can be changed without also changing the item count.
------------------------------
Date: Mon, 01 Jun 2015 22:18:07 -0700
From: Jim Gibson <JimSGibson@gmail.com>
Subject: Re: Puzzling Substitution Failure
Message-Id: <010620152218078912%JimSGibson@gmail.com>
In article <WsKdnTaYOKYYtfHInZ2dnUVZ57ydnZ2d@giganews.com>, Robbie
Hatley <see.my.sig@for.my.address> wrote:
> C.DeRykus : Ok, I'm going back and replying to the parts of your
> reply which I skipped-over before, because I've done some research
> and thinking on this.
>
> > Some peril attached unless you're sure about sources but
> > you can use the /ee switch to cause a double evaluation
>
> That actually does NOT sound at all like what I'm after.
> I need the Replacement to be treated as "regex replacement
> string language", not "Perl language".
There is no such thing as "regex replacement string language". The
unmodified s/// operator evaluates the replacement part as a
double-quoted string, which is normal Perl syntax.
> Ok, let's see what perldoc has to say.......
>
> % If the delimiter chosen is a single quote, no interpolation is
> % done on either the PATTERN or the REPLACEMENT. Otherwise, if
> % the PATTERN contains a $ that looks like a variable rather than
> % an end-of-string test, the variable will be interpolated into
> % the pattern at run-time.
>
> AH-HA. I see now what the problem was. s/// does *NOT* treat
> RegExp and Replacement differently. Both are interpolated, but
> ONLY ONCE. But since Replacements are more likely to have embedded
> back-references, that's DOUBLY indirect, so the substituted results
> of something like THIS:
Both portions of s/// are interpolated as single- or double-quoted
strings (depending upon the separator), but the subsequent processing
is much different. The left part is treated as a regex match operator,
and the right part is a replacement string.
> % A "/e" will cause the replacement portion to be treated as a
> % full-fledged Perl expression and evaluated right then and
> % there. It is, however, syntax checked at compile-time.
>
> Colorfully but vaguely written. What is "full-fledged" in this
> context? What is "right then and there" in this context?
> For that matter, what is "evaluated" in this context?
"Full-fledged" means you can have any Perl syntax, such as operators or
subroutine calls. You are not limited to string interpolation.
>
> But I can take a good guess: the author appears to be saying
> that the "replacement" string will be evaluated as a Perl
> expression. But for most replacement strings, that's NOT
> what we want!!!
Yes, it is. Usually, the replacement string is a double-quoted string,
which is also a valid Perl expression.
> % A second "e" modifier will cause the replacement portion
> % to be "eval"ed before being run as a Perl expression.
>
> Here he's saying, evaluate the string as a Perl expression,
> the take the RESULT, and evaluate THAT as being ANOTHER Perl
> expression, and substitute the result for the match. YIKES.
That seems to be exactly what you want. As you have figured out, you
can do the same thing with the eval() operator.
> No, I'll pass. I'm interested in being able to use ordinary
> RegExps and Replacements, not force the user of a script to
> come up with doubly-indirect meta-meta-Perl code.
It's two instances of evaluation instead of one (actually, one for each
'e' added). While it is an advanced feature, it is not that scary once
you learn it. It may be different from other languages, but that is why
we use different languages for different purposes.
--
Jim Gibson
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 4444
***************************************