Re: Hidden Secrets of PERL
by shmem (Chancellor) on Oct 11, 2006 at 09:56 UTC
|
I'd call you example pitfall or trap for the unwary
rather than a hidden treasure. It's normal behaviour, and
no, there is no such book - there's the perl documentation. Perl
just is like that, it's all about context.
Oh, wait - if you seek odd things, unexpected behaviour and such, have a
look at The Golf Book.
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] |
Re: Hidden Secrets of PERL
by zentara (Archbishop) on Oct 11, 2006 at 12:07 UTC
|
| [reply] |
Re: Hidden Secrets of PERL
by jdporter (Paladin) on Oct 11, 2006 at 14:24 UTC
|
| [reply] |
Re: Hidden Secrets of PERL
by blazar (Canon) on Oct 11, 2006 at 10:01 UTC
|
C has lot of reference materials and Books to explore the hidden treasures. Does PERL has any books/Reference to explore its hidden treasures.
It has excellent documentation in addition to many books.
I am looking something like,
$a = 10; $b = 20; print $a +$b;
perldoc -f print.
This code will not print 30 as there is ambiguity in the print statement. It treats $a as file handle and + before the $b as prefix operator and tries to print $b to $a.
There is no ambiguity, although one has to admit that the case may be confusing. But it's perfectly well documented.
Is there any place where these kind of hidden treasures are listed ?
Again, in the docs, in which as a perl_lover you will also be delighted to discover that it's also explained why there's not such a thing as PERL: see perldoc -q difference between "perl" and "Perl".
| [reply] [d/l] |
|
There is no ambiguity, although one has to admit that the case may be confusing. But it's perfectly well documented.
Eh, no... there is ambiguity as the syntax of this piece of code is ambiguous for the grammar.
Only, Perl has a well documented way to disambiguate this case.
Other ambiguities include code block versus anonymous hash, and the opening slash for regexes for optional function arguments:
map { $_ => length } @list # code block or hash?
rand /2 /m # division or regex?
Occasionally, in particular for the former example, Pelr makes an initial guess and guesses wrong, producing a syntax error further down in the parsing stream — too late to go back and try the other route. It requires a well known disambiguation trick to resolve the problem, early enough:
+{ $_ => length } # hashref
{ ; $_ => length } # code block
| [reply] [d/l] [select] |
|
print FILEHANDLE LIST
print LIST
print Prints a string or a list of strings. Returns true if success-
ful. FILEHANDLE may be a scalar variable name, in which case
the variable contains the name of or a reference to the file-
handle, thus introducing one level of indirection. (NOTE: If
FILEHANDLE is a variable and the next token is a term, it may
be misinterpreted as an operator unless you interpose a "+" or
put parentheses around the arguments.) If FILEHANDLE is omit-
ted, prints by default to standard output (or to the last
selected output channel--see "select"). If LIST is also omit-
ted, prints $_ to the currently selected output channel. To
set the default output channel to something other than STDOUT
use the select operation. The current value of $, (if any) is
printed between each LIST item. The current value of "$\" (if
any) is printed after the entire LIST has been printed.
Because print takes a LIST, anything in the LIST is evaluated
in list context, and any subroutine that you call will have one
or more of its expressions evaluated in list context. Also be
careful not to follow the print keyword with a left parenthesis
unless you want the corresponding right parenthesis to termi-
nate the arguments to the print--interpose a "+" or put paren-
theses around all the arguments.
Note that if you're storing FILEHANDLES in an array or other
expression, you will have to use a block returning its value
instead:
print { $files[$i] } "stuff\n";
print { $OK ? STDOUT : STDERR } "stuff\n";
The only part that hints about ambiguaty is the part I boldfaced. But it doesn't explain at all why it parses the statement differently whether there's a space between the third and fourth token. Not that I expect most programmers to know what the phrase next token is a term means. | [reply] |
Re: Hidden Secrets of PERL
by fenLisesi (Priest) on Oct 11, 2006 at 11:39 UTC
|
Not directly related to your question, $a and $b are not the best choices for variable names, as they are special. | [reply] [d/l] [select] |
Re: Hidden Secrets of PERL
by tilly (Archbishop) on Oct 11, 2006 at 22:42 UTC
|
I would try unravelling stuff in the Obfuscation section.
BTW congratulations. It has been a long time since something was pointed out to me about Perl that truly made me go, Ick! You succeeded.
BTW trading oddities, why do the following two programs print different things?
#######
## A ##
#######
use strict;
my $foo;
$foo = "outside";
for $foo (qw(a b c)) {
print_foo();
}
sub print_foo {
print "$foo\n";
}
__END__
#######
## B ##
#######
use strict;
our $foo;
$foo = "outside";
for $foo (qw(a b c)) {
print_foo();
}
sub print_foo {
print "$foo\n";
}
__END__
| [reply] [d/l] |
|
If the variable that is going to hold each value in an loop already exists as a lexical one (first example), foreach creates a new lexical whose scope is the loop block. If it exists as a package global (second example), foreach localizes it, thus making its scope dynamic. That's why second example's print_foo sees the dynamic content.
| [reply] [d/l] |
|
Indeed and this is documented in perlsyn under the heading "foreach loops":
The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localisation occurs only in a foreach loop.
OTOH, it doesn't seem to be really localized, instead, it appears to be a totally different lexical.
| [reply] [d/l] [select] |
|
Allow me to toil in some scrivener's work. In the "Non-Lexical Loop Iterators" section of PBP, the oracle speaks:
Always declare a for loop iterator variable with my.
and goes on to explain that, if there happens to be a lexical variable with the same name as the loop variable declared before the loop, that lexical variable is not reused within the loop, but a brand new independent lexical variable is implicitly created to take effect within the scope of the loop alone. Quoting the discussion there:
This behaviour is contrary to all reasonable expectation. Everywhere else in Perl, when you declare a lexical variable, it is visible throughout the remainder of its scope, unless another explicit my declaration hides it.
Update: wfsp sent me a link to this related node.
| [reply] [d/l] [select] |
|
The reason is history. The ability to write:
foreach my $variable (LIST) {...}
was relatively recent (5.004 I think). Before one had to write
my $variable;
foreach $variable (LIST) {...}
As usual, it's combining old Perl DWIM, new features and backwards compatability that leads to oddities like this.
Luckely, for most people, it all just works, and old programs don't break. | [reply] [d/l] [select] |
Re: Hidden Secrets of PERL
by jbrugger (Parson) on Oct 12, 2006 at 05:33 UTC
|
Not a real hidden secret, and mentioned on this site before: (however i use it, since it's save for my examle): the x operator.
have a look at the following example:
my $sql = join(",", @allsearchterms);
my $sth = $dbh->prepare("select * from table where value in($sql)");
# You need to place qutes arount the sql-items, but you'll get the poi
+nt here...
$sth->execute();
As you know, this isn't safe (sql Piggybacking)
Now concider the next code example:
my $qm = join ',', ('?') x @allsearchterms;
my $sth = $dbh->prepare("select * from table where value in($qm)");
$sth->execute(@allsearchterms);
As you see, a neat feature of Perl :)
Update:
code adjusted as suggested by Hue-Bond
"We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
| [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
Re: Hidden Secrets of PERL
by Anonymous Monk on Oct 13, 2006 at 11:14 UTC
|
@a=(1,2,3);
foreach my $r (@a) {
$r=2;
}
print @a;
Have a fun ;-) | [reply] [d/l] |
|
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |