Custom Search
|
Date: December 31, 2006
From: "Michael C. Toren" <mct-ivKz19tO56FeoWH0uzbU5w@xxxxxxxxxxxxxxxx>
In-reply-to:
<200612292141.15282.shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
References:
<200612292141.15282.shlomif@xxxxxxxxxxx>
On Fri, Dec 29, 2006 at 09:41:15PM +0200, Shlomi Fish wrote:
> A--B--F D--C
> | /
> |/
> E
[ ..]
> You should implement a function called "connected" that will receive
> such an input and return its connected components, where a connected
> component is such that for every two nodes in it, there's a path from
> one to the other. So for the graph above the function will return:
>
> [
> [[$A,$B],[$B,$E],[$B,$F],[$F,$E]],
> [[$D,$C]],
> ]
Would it perhaps make more sense for the "connected" function to return a
list of nodes, rather than links, for which there is some path connecting
them? For example:
[
[ $A, $B, $F, $E ],
[ $D, $C ]
]
Thanks,
-mct
Date: December 29, 2006
From: Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
Hi all and Happy New Year!
Here's a quiz for the new year. My sister received this challenge for her
college homework, and had to write some Standard ML code to solve it, a task
which I helped her with. I hope you enjoy it too.
=======================================
IMPORTANT: Please do not post solutions, hints, or other spoilers
until at least 60 hours after the date of this message.
Thanks.
We can represent a non-directed graph[1] (in the computer science sense) by
the following representation:
1. Every node (or vertex) will have an integer assinged to it.
2. Every link (or edge) will be represented as a pair of two integers - those
that were assigned to the the nodes it connects. Their order doesn't matter,
but as you see below should be preserved.
3. The entire graph will be represented as a list of such pairs representing
all the links of the graph.
So for example the following graph:
A--B--F D--C
| /
|/
E
Can be represnted by the following array ref:
[[$A,$B],[$B,$E],[$B,$F],[$D,$C],[$F,$E]]
You should implement a function called "connected" that will receive such an
input and return its connected components, where a connected component is such
that for every two nodes in it, there's a path from one to the other. So for
the graph above the function will return:
[
[[$A,$B],[$B,$E],[$B,$F],[$F,$E]],
[[$D,$C]],
]
One constraint is that the output should be ordered according to the order
of the links in the input. I.e: 1) the order of each link in each connected
component correspondence to their order in the input, and 2) the order of
the first links from each connected components corresponds to their order
in the input.
Input:
------
connected($list), where $list = \@list, and @list is made entirely of [$i,$j]
where $i and $j are integers.
Output:
-------
$ret = connected($list) where:
@comp1 = [ [$i1,$j1], [$i2, $j2], [$i3, $j3] ];
@comp2 = [ [$k1,$l1], [$k2, $l2],... ];
@components = ( \@comp1, \@comp2,... );
$ret = [ @components ];
---------------------------
Have fun!
Regards,
Shlomi Fish
[1] - http://en.wikipedia.org/wiki/Graph_theory
---------------------------------------------------------------------
Shlomi Fish shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx
Homepage: http://www.shlomifish.org/
Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.
Date: December 22, 2006
From: Mark Jason Dominus <mjd-ZxR0713JXSrQT0dZR+AlfA@xxxxxxxxxxxxxxxx>
In-reply-to:
Your message of "Wed, 20 Dec 2006 21:46:41 +0100." <4589A131.2050805-S6kZRaaRxOHk1uMJSBkQmQ@xxxxxxxxxxxxxxxx>
References:
<4589A131.2050805@xxxxxxxxxxxx>
> It may be verbose, but the code does have the advantage that you can > stick a breakpoint in the debugger and stop it exactly where you > want to. I know I've said this before, but in my opinion that is obviously a problem with the debugger, not with the code. The debugger is supposed to serve the programmer, not the other way around. There is absolutely no technical reason why the debugger could not be made to place a breakpoint inside a statement.
Date: December 20, 2006
From: David Landgren <david-S6kZRaaRxOHk1uMJSBkQmQ@xxxxxxxxxxxxxxxx>
In-reply-to:
<200612201418.38748.shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
References:
<D9C13100F14E4C4795A1E83B125B40350232B94F@xxxxxxxxxxxxxxxxx> <200612201418.38748.shlomif@xxxxxxxxxxx>
Shlomi Fish did write:
Hi! On Thursday 14 December 2006 00:05, Garrett, Philip (MAN-Corporate) wrote:Owen wrote:On Fri, 1 Dec 2006 16:35:44 +0200 Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx> wrote: 1: my (@list) = 2: ( 3: grep { $cgi->param("$prefix$_") } 4: map { /^${prefix}(\d+)$/ ? ($1) : () } 5: $cgi->param() 6: );Whenever I see construct like this that confuses me, I rewrite it so that the code actually goes in the same order as the operations, and turn all the temporary lists into named arrays. If the resulting code is clearer and does not negatively affect performance in a substantial way, I'll leave it. my $prefix = "form_field_"; # line 5 my @param_names = $cgi->param; # line 4 my @received_fields; for my $param_name (@param_names) { if ($param_name =~ /^${prefix}(\d+)$/) { my $field_number = $1; push @received_fields, $field_number; } } # line 3 my @list; for my $field_number (@received_fields) { if ($cgi->param("${prefix}${field_number}")) { push @list, $field_number; } } # @list now contains a list of numbers for which there are # populated form fields named "form_field_<number>". # ** it might contain duplicates, too # ** "populated" means non-empty and non-zeroWow-wa! You took a 3-liner and turned it into a 10-15 lines verbose monstrosity. If you're experienced enough you'll find the more concise map and grep version, as easy to understand as your code if not more. (Because there's less to read).
I wouldn't call it a monstrosity. It may be verbose, but the code does have the advantage that you can stick a breakpoint in the debugger and stop it exactly where you want to. Sometimes that's important too. The question is finding the right balance.
I'm dealing with a pile of crappy nested map/map/grep/for/map/grep chains in some code that a consultant wrote for me a few months ago and it's a royal pain.
David -- "It's overkill of course, but you can never have too much overkill."
Date: December 20, 2006
From: Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
In-reply-to:
<D9C13100F14E4C4795A1E83B125B40350232B94F-FGj4hxdlZKqKMbf6yP+JBGGXanvQGlWp@xxxxxxxxxxxxxxxx>
References:
<D9C13100F14E4C4795A1E83B125B40350232B94F@xxxxxxxxxxxxxxxxx>
Hi!
On Thursday 14 December 2006 00:05, Garrett, Philip (MAN-Corporate) wrote:
> Owen wrote:
> > On Fri, 1 Dec 2006 16:35:44 +0200
> >
> > Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx> wrote:
> >1: my (@list) =
> >2: (
> >3: grep { $cgi->param("$prefix$_") }
> >4: map { /^${prefix}(\d+)$/ ? ($1) : () }
> >5: $cgi->param()
> >6: );
>
> Whenever I see construct like this that confuses me, I rewrite it so
> that the
> code actually goes in the same order as the operations, and turn all the
> temporary lists into named arrays. If the resulting code is clearer and
> does
> not negatively affect performance in a substantial way, I'll leave it.
>
> my $prefix = "form_field_";
>
> # line 5
> my @param_names = $cgi->param;
>
> # line 4
> my @received_fields;
> for my $param_name (@param_names) {
> if ($param_name =~ /^${prefix}(\d+)$/) {
> my $field_number = $1;
> push @received_fields, $field_number;
> }
> }
>
> # line 3
> my @list;
> for my $field_number (@received_fields) {
> if ($cgi->param("${prefix}${field_number}")) {
> push @list, $field_number;
> }
> }
>
> # @list now contains a list of numbers for which there are
> # populated form fields named "form_field_<number>".
> # ** it might contain duplicates, too
> # ** "populated" means non-empty and non-zero
>
Wow-wa! You took a 3-liner and turned it into a 10-15 lines verbose
monstrosity. If you're experienced enough you'll find the more concise map
and grep version, as easy to understand as your code if not more. (Because
there's less to read). See:
http://www.paulgraham.com/popular.html (search for "brevity")
http://www.paulgraham.com/power.html
> Another way, but it doesn't really clear things up much:
>
> my @params = $cgi->param;
> my @numbers = map { /^${prefix}(\d+)$/ ? ($1) : () } @params;
> my @list = grep { $cgi->param("$prefix$_") } @numbers;
>
If you want the order of operations in the code to match their execution
order, you may want to look at the Pipe module:
http://cpan.uwinnipeg.ca/dist/Pipe
Using it one can write this untested code:
my @list = Pipe->for($cgi->param)
->map(sub { shift =~ /^${prefix}(\d+)$/ ? ($1) : ()})
->grep( sub { $cgi->param("$prefix$_[0]") })->run;
Regards,
Shlomi Fish
---------------------------------------------------------------------
Shlomi Fish shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx
Homepage: http://www.shlomifish.org/
Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.
Date: December 16, 2006
From: demerphq <demerphq-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
In-reply-to:
<45830EEB.5090805-SqBW2fPs1Pc@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <17793.53000.969558.597723@xxxxxxxxxxxx> <45830EEB.5090805@xxxxxxx>
On 12/15/06, Martijn Lievaart <m@xxxxxxx> wrote:
Joshua Kronengold wrote: >As of 5.8.5, perlre says this: > > The numbered match variables ($1, $2, $3, etc.) and the related punctu- > ation set ($+, $&, , , and $^N) are all dynamically scoped until > the end of the enclosing block or until the next successful match, > whichever comes first. (See "Compound Statements" in perlsyn.) > >Which on careful analysis (ie, mine, just now :^) would appear to match >the described and tested for behavior -- that, the dynamic scope of >numbered match variables expires at the end of their enclosing block, >making subroutine calls comparatively safe. > >As such, the behavior -is- documented -- and can be relied upon when >coding for modern perls. > > Yes, but I had to read this a few times to really get it. A new match can occur in the same block or another block called from within this block. If it occurs in the same block, you clobber $n. If it occurs in another block, you clobber $n until the end of that block. After that block $n is again the previous value.
No, this is wrong. At least as I understand what you have said. This is what happens: When a match involving s/// or m// is successful perl localizes an internal pointer called PL_curpm and sets it to point at the regexp structure for the most recent match. At scope exit all vars localized in that scope are rolled back to their previous values, including ones localized invisibly by the core such vars like PL_curpm. The regex magic vars are implemented as ties that access data held in the structure pointed to by PL_curpm. Therefore the regex magic vars access the results of the most recently executed successful match in the current scope. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"
Date: December 15, 2006
From: Martijn Lievaart <m@xxxxxxx>
In-reply-to:
<17793.53000.969558.597723-iBiTjYQMp5NWk0Htik3J/w@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <17793.53000.969558.597723@xxxxxxxxxxxx>
Joshua Kronengold wrote:
As of 5.8.5, perlre says this: The numbered match variables ($1, $2, $3, etc.) and the related punctu- ation set ($+, $&, , , and $^N) are all dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first. (See "Compound Statements" in perlsyn.) Which on careful analysis (ie, mine, just now :^) would appear to match the described and tested for behavior -- that, the dynamic scope of numbered match variables expires at the end of their enclosing block, making subroutine calls comparatively safe. As such, the behavior -is- documented -- and can be relied upon when coding for modern perls.
Yes, but I had to read this a few times to really get it. A new match can occur in the same block or another block called from within this block. If it occurs in the same block, you clobber $n. If it occurs in another block, you clobber $n until the end of that block. After that block $n is again the previous value.
Thanks to everyone on this thread, learn something new every day! M4
Date: December 15, 2006
From: Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
In-reply-to:
<86lklb1mpq.fsf-QQWfiD5J9rlvIiBbVGLYw0EOCMrvLtNR@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <20061214084046.d03dd17d.rcook@xxxxxxxxxxx> <86lklb1mpq.fsf@xxxxxxxxxxxxxxxxxxx>
On Wednesday 13 December 2006 23:59, Randal L. Schwartz wrote:
> >>>>> "Owen" == Owen <rcook-iMDvLBO0GCq6c6uEtOJ/EA@xxxxxxxxxxxxxxxx> writes:
> >>
> >> my (@list) =
> >> (
> >> grep { $cgi->param("$prefix$_") }
> >> map { /^${prefix}(\d+)$/ ? ($1) : () }
> >> $cgi->param()
> >> );
>
> Owen> I have waited 60 hours and more now. Just wondering if there was a
> Owen> follow up to the message because like the friend above, I too have
> Owen> problems understanding what was going on!
>
> Given a $prefix like "addressline", @list will contain a list of all
> numbers tailed from elements like "addressline1" and "addressline37" that
> contain non-false form values (1 and 37 in this case).
>
> I don't think that'd be as useful as hand coding this instead:
>
> my @addressline = grep { /^addressline/ and defined param($_) } param();
>
> That's how I'd do that instead. To use them, you're gonna need to go
> back to the full $prefix form anyway!
Actually, this will return the CGI parameters together with the $prefix. I was
interested in their names without the prefix. So if I have "toggle1"
and "toggle37", I'm interested in "1" and "37" respectively.
I've needed them because they were IDs of records in a database table that I
needed to do a bulk operation on.
Regards,
Shlomi Fish
---------------------------------------------------------------------
Shlomi Fish shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx
Homepage: http://www.shlomifish.org/
Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.
Date: December 15, 2006
From: merlyn-DiZw3cqpylQkmLvzuZlaBw@xxxxxxxxxxxxxxxx (Randal L. Schwartz)
In-reply-to:
<4ce365ec0612141525k6be991fax481baeaadb4f6485-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <17793.53000.969558.597723@xxxxxxxxxxxx> <4ce365ec0612141525k6be991fax481baeaadb4f6485@xxxxxxxxxxxxxx>
>>>>> "Jay" == Jay Savage <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
>>>>> writes:
Jay> $1 is implicitly localized to the enclosing block, not to the operator
Jay> itself. That means that something like the following would be
Jay> dangerous if $1 weren't read-only:
Jay> {
Jay> m/(.)/;
Jay> ⊂
Jay> print $1;
Jay> }
It's dangerous anyway. Never use $1 unless you've tested the match!
$1 is *set* on a match, but not *reset* on a fail.
Consider:
"xyz" =~ /(x..)/; # $1 is now xyz
"xyz" =~ /(y..)/; # $1 is *still* xyz
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn-DiZw3cqpylQkmLvzuZlaBw@xxxxxxxxxxxxxxxx>
<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!
Date: December 14, 2006
From: "Jay Savage" <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
In-reply-to:
<17793.53000.969558.597723-iBiTjYQMp5NWk0Htik3J/w@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <17793.53000.969558.597723@xxxxxxxxxxxx>
On 12/14/06, Joshua Kronengold <mneme@xxxxxx> wrote:
1. The (as it turned out, ambiguously stated) point on the table was that the nature of the variable (ie, dynamic vs lexical) was the cause of the operation now being safe.
It's not the scoping that makes it safe. Because we're talking about
an operator and not a subroutine, scope has to with the contest in
which the operator appears:
{ # Begin scope
blah....blah...
m/(blah)/;
blah...blah...
# End scope }
$1 is implicitly localized to the enclosing block, not to the operator
itself. That means that something like the following would be
dangerous if $1 weren't read-only:
{
m/(.)/;
⊂
print $1;
}
Because $1 is dynamically and not lexically scoped, &sub could
overwrite $1 if it were writable. It's the RO that saves you.
2. It simply hadn't occured to me that a line-operation (as opposed to a block operation) would do implicit localization -- because I'd never (to my memory) encountered an operation in perl that did that before. Is there another one? local() localizes a dynamically scoped variable, of course. But aside from, now, the match operator and its relatives, I don't think I've seen this kind of "localizing inside the block as a side effect" behavior before.
The only two I can think of are eval and system. @? and $! function in
the same way. m//, though, is unique in the sheer number of local
variable it exports to the enclosing scope. It is kind of strange,
though, that
{
m//;
}
implicitly becomes
{
local ($1,$2...$n, $&,&'); # etc., etc.
m//;
}
[snip]
>But it looks like we're all on the same page now. $1 is dynamically >scoped. s/(.)/⊂ $1/e is probably a safe construct, even if &sub >performs its own match. Yeah. Neat. (tests). Works, too. >That doesn't, though, mean it's good practice >because it may not be backwards-compatible; it relies on undocumented >and unguaranteed behavior of m//. Hmm. Mabye. As of 5.8.5, perlre says this: The numbered match variables ($1, $2, $3, etc.) and the related punctu- ation set ($+, $&, , , and $^N) are all dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first. (See "Compound Statements" in perlsyn.) Which on careful analysis (ie, mine, just now :^) would appear to match the described and tested for behavior -- that, the dynamic scope of numbered match variables expires at the end of their enclosing block, making subroutine calls comparatively safe. As such, the behavior -is- documented -- and can be relied upon when coding for modern perls.
Learn something new every day. Best, -- jay -------------------------------------------------- This email and attachment(s): [ ] blogable; [ x ] ask first; [ ] private and confidential daggerquill [at] gmail [dot] com http://www.tuaw.com http://www.downloadsquad.com http://www.engatiki.org values of β will give rise to dom!
Date: December 14, 2006
From: "Ben Prew" <btp-a09SyBuiYrA@xxxxxxxxxxxxxxxx>
In-reply-to:
<20061214222207.GA6683-dNnkglbcI8AYkl5+HhvCNA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <24f4b2e80612141404j5e392987nf3f2a7eab17ef67f@xxxxxxxxxxxxxx> <20061214222207.GA6683@xxxxxxxxxxxxxxx>
Apparently I need to read more before I go posting things ;). Josh said that is was an operator, not a sub, which makes more sense. And then Jay also remarked that m// did an implicit local $1 = $1, which was my understanding as well. So, everything is clear to me now, and I apologize for appearing obtuse, if in fact I did. Thanks -- --Ben
Date: December 14, 2006
From: Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx>
In-reply-to:
<4ce365ec0612141334y26037ce0g56c890433a25592e-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx>
Jay Savage writes:
>It certainly seemed that you didn't quite "get" the concept of
>local-vs.-lexical variables. To wit:
To you. I started out with saying "you said local -- did you mean
dynamic or lexical?" (more or less)
Assuming from that that I didn't understand the difference seems to be
missing the point.
> > However, it seems that at least in modern perls, $1 is -lexically-
>> scoped. That seems new. But good:
>Ronald and I attempted to set you straight.
Easy enough, since I had simply drawn incorrect assumptions from my
oversimplified tests -- because Ronald seemed to be saying that the
nature of the variable (rather than that of the operation) was the
reason it wasn't being overwritten. I didn't regressively test the
other side of the question (ie, whether a value was visible inside a
subroutine prior to any operations being performed) for two reasons:
1. The (as it turned out, ambiguously stated) point on the table was
that the nature of the variable (ie, dynamic vs lexical) was the
cause of the operation now being safe.
2. It simply hadn't occured to me that a line-operation (as opposed to
a block operation) would do implicit localization -- because I'd
never (to my memory) encountered an operation in perl that did that
before. Is there another one? local() localizes a dynamically
scoped variable, of course. But aside from, now, the match
operator and its relatives, I don't think I've seen this kind of
"localizing inside the block as a side effect" behavior before.
>In your private email you said that one, you mistyped and didn't catch
>it, and two, you were assuming a 'different contextual meaning to
>"locally scoped"," as it somehow relates to the context of s//&sub/e.
Not mistyped, so much as that my assumptions changed from the point at
which I wrote the first clause to the later parts of my response. I
contradicted myself later, which was intentional -- but I didn't
remember what I'd written earlier, so didn't correct it.
>attention- to the erring phrase--and as for the second, I'd certainly
>advise against using standard jargon like "localized" and "local
>scope" in non-standard ways.
I'm actually not familiar with "local scope" except as jargon for
"dynamic scope" -- but made the assumption that Ronald was using it in
a non-standard way. So it goes. :)
>But it looks like we're all on the same page now. $1 is dynamically
>scoped. s/(.)/⊂ $1/e is probably a safe construct, even if &sub
>performs its own match.
Yeah. Neat. (tests). Works, too.
>That doesn't, though, mean it's good practice
>because it may not be backwards-compatible; it relies on undocumented
>and unguaranteed behavior of m//.
Hmm. Mabye.
As of 5.8.5, perlre says this:
The numbered match variables ($1, $2, $3, etc.) and the related punctu-
ation set ($+, $&, , , and $^N) are all dynamically scoped until
the end of the enclosing block or until the next successful match,
whichever comes first. (See "Compound Statements" in perlsyn.)
Which on careful analysis (ie, mine, just now :^) would appear to match
the described and tested for behavior -- that, the dynamic scope of
numbered match variables expires at the end of their enclosing block,
making subroutine calls comparatively safe.
As such, the behavior -is- documented -- and can be relied upon when
coding for modern perls.
--
Joshua Kronengold (mneme@(io.com, labcats.org)) |\ _,,,--,,_ ,)
--^-- "Did you know, if you increment enough, you /,`.-'`' -, ;-;;'
/\\ get an extra digit?" "I knew," weeps Six. |,4- ) )-,_ ) /\
/-\\\ "We knew. But we had forgotten." '---''(_/--' (_/-'
Date: December 14, 2006
From: Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
In-reply-to:
<24f4b2e80612141404j5e392987nf3f2a7eab17ef67f-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx> <24f4b2e80612141404j5e392987nf3f2a7eab17ef67f@xxxxxxxxxxxxxx>
On Thu, Dec 14, 2006 at 02:04:36PM -0800, Ben Prew wrote: > So the thing I don't understand is, if a pattern match is the same > thing as a subroutine call, and it's localizing the match, why do I > see the new value of $1 in the line after it. No one has said that a pattern match is the same thing as a subroutine call. A pattern matches localizes the regex variables in the current scope. It really is just that simple. Ronald
Date: December 14, 2006
From: "Ben Prew" <btp-a09SyBuiYrA@xxxxxxxxxxxxxxxx>
In-reply-to:
<4ce365ec0612141334y26037ce0g56c890433a25592e-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx> <4ce365ec0612141334y26037ce0g56c890433a25592e@xxxxxxxxxxxxxx>
On 12/14/06, Jay Savage <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx> wrote:
On 12/14/06, Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx> wrote:
1) whether $1 is lexically or dynamically scoped (it's dynamic), and 2) whether the grounds on which the proposal that $1 is lexical are justified (they aren't).
So the thing I don't understand is, if a pattern match is the same
thing as a subroutine call, and it's localizing the match, why do I
see the new value of $1 in the line after it.
ex.
'bar' =~ /(bar)/;
warn $1;
'baz' =~ /(baz)/;
warn $1;
And, this prints out bar, baz, which I expect. But, it's equivalent to this:
local $foo;
regex_match_to_bar($foo);
warn $foo;
local $foo = $foo;
regex_match_to_baz($foo);
warn $foo;
sub regex_match_to_bar
{
$foo = 'bar';
}
sub regex_match_to_baz
{
$foo = 'baz';
}
But not this:
local $foo = 'default';
regex_match_to_bar($foo);
warn $foo;
regex_match_to_baz($foo);
warn $foo;
sub regex_match_to_bar
{
local $foo = $foo;
$foo = 'bar';
}
sub regex_match_to_baz
{
local $foo = $foo;
$foo = 'baz';
}
And, what I hear from you guys is "regex's are just another name for a
method call, and scope doesn't matter". However, there's some sort of
implicit addition of local scoping going on that I didn't explicitly
ask for, and it doesn't work the way it would if the regex call was
*really* just a subroutine call.
Or is there something I'm missing?
--
--Ben
Date: December 14, 2006
From: "Garrett, Philip \(MAN-Corporate\)" <Philip.Garrett-m43M5rQ15AJBDgjK7y7TUQ@xxxxxxxxxxxxxxxx>
Owen wrote:
> On Fri, 1 Dec 2006 16:35:44 +0200
> Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx> wrote:
>
>> Hi all!
>>
>> Well, it's been a while since we had a quiz so here's another what
>> does this code do quiz:
>>
>> {{{{{{
>> my (@list) =
>> (
>> grep { $cgi->param("$prefix$_") }
>> map { /^${prefix}(\d+)$/ ? ($1) : () }
>> $cgi->param()
>> );
>> }}}}}}
>>
>> $cgi is a CGI.pm instance. (in case you couldn't guess.)
>>
>> A friend of mine whose perl is quite rusty had problems
>> understanding this code.
>>
>> What does this code do? And can you guess in what context it was
>> used?
>>
>> I'll reveal the solution after a 60 hours quota, and until then
>> please send them to me in private.
>
>
> I have waited 60 hours and more now. Just wondering if there was a
> follow up to the message because like the friend above, I too have
> problems understanding what was going on!
>1: my (@list) =
>2: (
>3: grep { $cgi->param("$prefix$_") }
>4: map { /^${prefix}(\d+)$/ ? ($1) : () }
>5: $cgi->param()
>6: );
Whenever I see construct like this that confuses me, I rewrite it so
that the
code actually goes in the same order as the operations, and turn all the
temporary lists into named arrays. If the resulting code is clearer and
does
not negatively affect performance in a substantial way, I'll leave it.
my $prefix = "form_field_";
# line 5
my @param_names = $cgi->param;
# line 4
my @received_fields;
for my $param_name (@param_names) {
if ($param_name =~ /^${prefix}(\d+)$/) {
my $field_number = $1;
push @received_fields, $field_number;
}
}
# line 3
my @list;
for my $field_number (@received_fields) {
if ($cgi->param("${prefix}${field_number}")) {
push @list, $field_number;
}
}
# @list now contains a list of numbers for which there are
# populated form fields named "form_field_<number>".
# ** it might contain duplicates, too
# ** "populated" means non-empty and non-zero
Another way, but it doesn't really clear things up much:
my @params = $cgi->param;
my @numbers = map { /^${prefix}(\d+)$/ ? ($1) : () } @params;
my @list = grep { $cgi->param("$prefix$_") } @numbers;
Regards,
Philip
Date: December 14, 2006
From: "Ben Prew" <btp-a09SyBuiYrA@xxxxxxxxxxxxxxxx>
In-reply-to:
<20061214183457.GD62246-dNnkglbcI8AYkl5+HhvCNA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <20061214172105.GC62246@xxxxxxxxxxxxxxx> <24f4b2e80612141028v3536162bpfca50363b1322564@xxxxxxxxxxxxxx> <20061214183457.GD62246@xxxxxxxxxxxxxxx>
On 12/14/06, Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx> wrote:
Yes, I would have expected bar, bar, blah, bar, if you had properly localized $foo inside the subroutine:
Ahh, i think now I understand, regex capture variables ($1, $2... ) have their own, unique scope, that is neither dynamic nor lexical. So, your example is correct, but only for things that have these nifty special scoping rules. Also, I agree with you that if you had localized $foo properly in the subroutine, then it would have printed bar, bar, blah, bar. But, localizing $foo properly is a condition of the subroutine owner, and since I can't guarantee (without looking) that a subroutine will localize its variables properly, then I should be aware that it could bite me, and that not all code should assume that just because they localize a variable properly, that everyone else will as well. -- --Ben
Date: December 14, 2006
From: "Jay Savage" <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
In-reply-to:
<17793.40618.674751.297239-iBiTjYQMp5NWk0Htik3J/w@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx> <17793.40618.674751.297239@xxxxxxxxxxxx>
On 12/14/06, Joshua Kronengold <mneme@xxxxxx> wrote:
I'd send the same flame that I sent to your (identical) private response, but I don't see the point. Suffice it to say that you seem to have lost track of the conversation.
Sorry about the personal reply. It was intended to go the list in the first place. I still don't understand why the Perl lists don't set reply-to-list... Anyway, I wouldn't call it a flame. As far as losing track of the conversation, well, threads have a life of their own, and this one seems to have turned into a discussion of 1) whether $1 is lexically or dynamically scoped (it's dynamic), and 2) whether the grounds on which the proposal that $1 is lexical are justified (they aren't). It certainly seemed that you didn't quite "get" the concept of local-vs.-lexical variables. To wit: > However, it seems that at least in modern perls, $1 is -lexically-
scoped. That seems new. But good:
Ronald and I attempted to set you straight. After all, this list is about learning, and hopefully trying not to spread misinformation, right? In your private email you said that one, you mistyped and didn't catch it, and two, you were assuming a 'different contextual meaning to "locally scoped"," as it somehow relates to the context of s//&sub/e. The first part could happen to anyone--although it's difficult for your readers to suspect a mistype when you go out of your way to -draw attention- to the erring phrase--and as for the second, I'd certainly advise against using standard jargon like "localized" and "local scope" in non-standard ways. It's a good way to guarantee just this kind of confusion. But it looks like we're all on the same page now. $1 is dynamically scoped. s/(.)/⊂ $1/e is probably a safe construct, even if &sub performs its own match. That doesn't, though, mean it's good practice because it may not be backwards-compatible; it relies on undocumented and unguaranteed behavior of m//. We now return this list to its regularly scheduled silence. Best, --jay -------------------------------------------------- This email and attachment(s): [ ] blogable; [ x ] ask first; [ ] private and confidential daggerquill [at] gmail [dot] com http://www.tuaw.com http://www.downloadsquad.com http://www.engatiki.org values of β will give rise to dom!
Date: December 14, 2006
From: Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx>
In-reply-to:
<4ce365ec0612141027w6c206358yb33ce53fded85980-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx> <4ce365ec0612141027w6c206358yb33ce53fded85980@xxxxxxxxxxxxxx>
I'd send the same flame that I sent to your (identical) private
response, but I don't see the point.
Suffice it to say that you seem to have lost track of the
conversation.
--
Joshua Kronengold (mneme@(io.com, labcats.org)) |\ _,,,--,,_ ,)
--^-- "Did you know, if you increment enough, you /,`.-'`' -, ;-;;'
/\\ get an extra digit?" "I knew," weeps Six. |,4- ) )-,_ ) /\
/-\\\ "We knew. But we had forgotten." '---''(_/--' (_/-'
Date: December 14, 2006
From: Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
In-reply-to:
<24f4b2e80612141028v3536162bpfca50363b1322564-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <20061214172105.GC62246@xxxxxxxxxxxxxxx> <24f4b2e80612141028v3536162bpfca50363b1322564@xxxxxxxxxxxxxx>
On Thu, Dec 14, 2006 at 10:28:11AM -0800, Ben Prew wrote:
> On 12/14/06, Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
> wrote:
> >It's exactly the same behavior as you would get by using local() on a
> >regular variable. The value is visible outside the block, but when the
> >block exits the previous value is restored. If it were lexically scoped,
> >the value would not be visible outside the block.
>
> Actually, I agree with Josh, the local() method introduces dynamic
> scope, so it would behave very differently. ex
> #!/usr/bin/perl
>
> local $foo;
> $foo = 'bar';
> warn $foo;
> baz();
> warn $foo;
>
> sub baz
> {
> warn $foo;
> $foo = 'blah';
> warn $foo;
> }
>
> prints:
>
> bar at test.pl line 5.
> bar at test.pl line 11.
> blah at test.pl line 13.
> blah at test.pl line 7.
>
> But, it sounded like you would have expected:
>
> bar, bar, blah, bar....
Yes, I would have expected bar, bar, blah, bar, if you had properly
localized $foo inside the subroutine:
#!/usr/bin/perl
$foo = 'bar';
warn $foo;
baz();
warn $foo;
sub baz
{
local $foo = $foo;
warn $foo;
$foo = 'blah';
warn $foo;
}
Ronald
Date: December 14, 2006
From: "Jay Savage" <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
In-reply-to:
<4ce365ec0612141020u20c4d72hac4d212f114e20d5-JsoAwUIsXosN+BqQ9rBEUg@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <4ce365ec0612141020u20c4d72hac4d212f114e20d5@xxxxxxxxxxxxxx>
On 12/14/06, Joshua Kronengold <mneme@xxxxxx> wrote:
Ronald J Kimball writes: >On Thu, Dec 14, 2006 at 09:35:57AM -0600, Joshua Kronengold wrote: >> Shlomi Fish writes: >> >When I said that $1 may be destroyed by the param method call, he noted >> >that $1 was locally scoped, which indeed seems to be the case. So my >> >code should be written like that instead. >> Wait, what? >> >> This seems wrong -- since $1 is locally scoped, (not lexically >> scoped), it -can- be technically destroyed by the param call, so you >> don't want to do this, even if you can. (if param is written not to >> squash $1, it's bad practice to trust in this). > >No, it can't be destroyed by the param call. When the param() exits, $1 is >restored to its previous value, because it is locally scoped. That's not locally scoped, that's lexically scoped. At least as a perl-centric coder, locally scoped would seem to be associated with "local" -- ie, dynamically scoped.
I think we're missing the point here: m// is an operator, not a block. The behavior it exhibits isn't tied to the scoping of the variables it employs. $1 is dynamically scoped. Subroutines declared anywhere will be able to see their caller's $1. This is both demonstrably true and clearly stated in perlsub and elsewhere. [snip]
>I'm not sure what you're trying to show with that code. That my assumptions were wrong? I remember "losing" $1 due to subroutine calls with perl 5.003 or so, but clearly the implementation has changed.
This has very little to do with scoping, and very mush to do with the behavior of the operator. The regex engine, apparently, now dynamically scopes match vars for every invocation. Think of every invocation of m// no beginning with something like 'local $1 = $1'. This was not (consistently?) the previous behavior, but it's the interface that's changed, not the scope, or, more importantly, the type of scope.
>Here's an example
>that shows that $1 is locally, not lexically, scoped:
...
>{
> /(a)/;
> print "$1\n";
> foo();
...
>sub foo {
> print "$1\n";
>If $1 were lexically scoped, the value it gets within the block wouldn't be
>visible in the subroutine, which is outside the block.
Exactly.
Ah. So what you are actually saying is "Match operators localize $1"?
No. what he's saying is that you can't determine whether a sub is
seeing dynamic or lexical variable from the value of the variable
after the sub. These two bits of code will produce exactly the same
results:
{
local $aa = 1;
{
local $aa = 2;
}
print $aa;
}
{
my $aa = 1;
{
my $aa = 2;
{
print $aa;
}
That's very different than "is locally scoped", and much clearer, but I'd prefer people didn't use the latter; it's as misleading as saying "$_ is locally scoped".
And wrong. $1 is "locally scoped," or, more properly, dynamically scoped, which should clear up and confusion.
(the latter being both not true (most constructs that override $_ automatically actually alias it to something else -- which I assume involves pushing the reference to something else onto it's stack, and which is similar, but not identical to localization), and not universally relied upon (see while(<>)).
- Hide quoted text - Again, what most constructors do has noting to do with whether the variables they inherit are lexically or dynamically scoped. $_ is in fact dynamically scoped. There's a failsafe litmus test here: try calling my and local on any variable you're unsure of. One or the other operator will fail with either "can't use global _ in 'my" or "can't localize lexical variable". If you're ever in doubt about a variables scope, just try to localize it. HTH, --jay -------------------------------------------------- This email and attachment(s): [ ] blogable; [ x ] ask first; [ ] private and confidential daggerquill [at] gmail [dot] com http://www.tuaw.com http://www.downloadsquad.com http://www.engatiki.org values of β will give rise to dom!
Date: December 14, 2006
From: "Jay Savage" <daggerquill-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx>
In-reply-to:
<20061214172105.GC62246-dNnkglbcI8AYkl5+HhvCNA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx> <20061214172105.GC62246@xxxxxxxxxxxxxxx>
On 12/14/06, Ronald J Kimball <rjk@xxxxxxxxxx> wrote:
On Thu, Dec 14, 2006 at 10:50:54AM -0600, Joshua Kronengold wrote: > Ronald J Kimball writes: > >No, it can't be destroyed by the param call. When the param() exits, $1 is > >restored to its previous value, because it is locally scoped. > > That's not locally scoped, that's lexically scoped. At least as a > perl-centric coder, locally scoped would seem to be associated with > "local" -- ie, dynamically scoped. It's exactly the same behavior as you would get by using local() on a regular variable. The value is visible outside the block, but when the block exits the previous value is restored. If it were lexically scoped, the value would not be visible outside the block. > >If $1 were lexically scoped, the value it gets within the block wouldn't be > >visible in the subroutine, which is outside the block. > > Ah. So what you are actually saying is "Match operators localize $1"? You're right, that's a more accurate way of describing the behavior. Thanks. Ronald
-- -------------------------------------------------- This email and attachment(s): [ ] blogable; [ x ] ask first; [ ] private and confidential daggerquill [at] gmail [dot] com http://www.tuaw.com http://www.downloadsquad.com http://www.engatiki.org values of β will give rise to dom!
Date: December 14, 2006
From: Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
In-reply-to:
<17793.33006.121678.100171-iBiTjYQMp5NWk0Htik3J/w@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx> <17793.33006.121678.100171@xxxxxxxxxxxx>
On Thu, Dec 14, 2006 at 10:50:54AM -0600, Joshua Kronengold wrote: > Ronald J Kimball writes: > >No, it can't be destroyed by the param call. When the param() exits, $1 is > >restored to its previous value, because it is locally scoped. > > That's not locally scoped, that's lexically scoped. At least as a > perl-centric coder, locally scoped would seem to be associated with > "local" -- ie, dynamically scoped. It's exactly the same behavior as you would get by using local() on a regular variable. The value is visible outside the block, but when the block exits the previous value is restored. If it were lexically scoped, the value would not be visible outside the block. > >If $1 were lexically scoped, the value it gets within the block wouldn't be > >visible in the subroutine, which is outside the block. > > Ah. So what you are actually saying is "Match operators localize $1"? You're right, that's a more accurate way of describing the behavior. Thanks. Ronald
Date: December 14, 2006
From: Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx>
In-reply-to:
<20061214162427.GA62246-dNnkglbcI8AYkl5+HhvCNA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx> <20061214162427.GA62246@xxxxxxxxxxxxxxx>
Ronald J Kimball writes:
>On Thu, Dec 14, 2006 at 09:35:57AM -0600, Joshua Kronengold wrote:
>> Shlomi Fish writes:
>> >When I said that $1 may be destroyed by the param method call, he noted
>> >that $1 was locally scoped, which indeed seems to be the case. So my
>> >code should be written like that instead.
>> Wait, what?
>>
>> This seems wrong -- since $1 is locally scoped, (not lexically
>> scoped), it -can- be technically destroyed by the param call, so you
>> don't want to do this, even if you can. (if param is written not to
>> squash $1, it's bad practice to trust in this).
>
>No, it can't be destroyed by the param call. When the param() exits, $1 is
>restored to its previous value, because it is locally scoped.
That's not locally scoped, that's lexically scoped. At least as a
perl-centric coder, locally scoped would seem to be associated with
"local" -- ie, dynamically scoped.
>> perl -Mstrict -e 'sub test { shift =~ /b(.*)/ and return $1 }; my
>> $str = "abababa"; print +($str =~ /((?:ba){1,2})/ and print
>> test($str),"\n") ? $1 : "no","\n"'
>> ababa
>> baba
>
>I'm not sure what you're trying to show with that code.
That my assumptions were wrong? I remember "losing" $1 due to
subroutine calls with perl 5.003 or so, but clearly the implementation
has changed.
>Here's an example
>that shows that $1 is locally, not lexically, scoped:
...
>{
> /(a)/;
> print "$1\n";
> foo();
...
>sub foo {
> print "$1\n";
>If $1 were lexically scoped, the value it gets within the block wouldn't be
>visible in the subroutine, which is outside the block.
Ah. So what you are actually saying is "Match operators localize $1"?
That's very different than "is locally scoped", and much clearer, but
I'd prefer people didn't use the latter; it's as misleading as saying
"$_ is locally scoped".
(the latter being both not true (most constructs that override $_
automatically actually alias it to something else -- which I assume
involves pushing the reference to something else onto it's stack, and
which is similar, but not identical to localization), and not
universally relied upon (see while(<>)).
>So, there's no reason not to write the code as I suggested. :)
No, there isn't! (and in fact, $1 is also read-only, which avoids the
possibility of bad actors changing it like they can $_).
But there -is- a reason to be more careful in explaining why.
--
Joshua Kronengold (mneme@(io.com, labcats.org)) |\ _,,,--,,_ ,)
--^-- "Did you know, if you increment enough, you /,`.-'`' -, ;-;;'
/\\ get an extra digit?" "I knew," weeps Six. |,4- ) )-,_ ) /\
/-\\\ "We knew. But we had forgotten." '---''(_/--' (_/-'
Date: December 14, 2006
From: Mark Jason Dominus <mjd-ZxR0713JXSrQT0dZR+AlfA@xxxxxxxxxxxxxxxx>
In-reply-to:
Your message of "Wed, 13 Dec 2006 14:26:56 PST." <45807E30.2020003-XkckGZ689+c@xxxxxxxxxxxxxxxx>
References:
<45807E30.2020003@xxxxxxxx>
> I'm getting failed sends of my list submissions. Methinks those should > stay with the list maintainer, or? They should, but it's impossible to prevent list subscribers (or their mail admins) from setting up broken autoresponders that reply to the "From" address instead of to the envelope sender address. If I get any inappropriate bounce messages in reply to this message, I'll try to deal with them appropriately.
Date: December 14, 2006
From: Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
In-reply-to:
<17793.28509.439406.47451-iBiTjYQMp5NWk0Htik3J/w@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx> <17793.28509.439406.47451@xxxxxxxxxxxx>
On Thu, Dec 14, 2006 at 09:35:57AM -0600, Joshua Kronengold wrote:
> Shlomi Fish writes:
> >When I said that $1 may be destroyed by the param method call, he noted
> >that $1 was locally scoped, which indeed seems to be the case. So my
> >code should be written like that instead.
>
> Wait, what?
>
> This seems wrong -- since $1 is locally scoped, (not lexically
> scoped), it -can- be technically destroyed by the param call, so you
> don't want to do this, even if you can. (if param is written not to
> squash $1, it's bad practice to trust in this).
No, it can't be destroyed by the param call. When the param() exits, $1 is
restored to its previous value, because it is locally scoped.
> However, it seems that at least in modern perls, $1 is -lexically-
> scoped. That seems new. But good:
>
> perl -Mstrict -e 'sub test { shift =~ /b(.*)/ and return $1 }; my
> $str = "abababa"; print +($str =~ /((?:ba){1,2})/ and print
> test($str),"\n") ? $1 : "no","\n"'
> ababa
> baba
I'm not sure what you're trying to show with that code. Here's an example
that shows that $1 is locally, not lexically, scoped:
#!perl
$_ = 'abc';
{
/(a)/;
print "$1\n";
foo();
print "$1\n";
}
sub foo {
print "$1\n";
/(b)/;
print "$1\n";
}
__END__
a
a
b
a
If $1 were lexically scoped, the value it gets within the block wouldn't be
visible in the subroutine, which is outside the block.
Furthermore, although foo() changes the value of $1 to 'b', after it
returns the value of $1 has been restored to 'a'.
So, there's no reason not to write the code as I suggested. :)
Ronald
Date: December 14, 2006
From: Joshua Kronengold <mneme-Xhj3G7Rj6JI@xxxxxxxxxxxxxxxx>
In-reply-to:
<200612140513.03284.shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <200612140513.03284.shlomif@xxxxxxxxxxx>
Shlomi Fish writes:
><<<<<<<<
>my(@list) =
>(
> map { /^${prefix}(\d+)$/ && $cgi->param($_) ? $1 : () }
> $cgi->param()
>);
>>>>>>>>>
>
>When I said that $1 may be destroyed by the param method call, he noted that
>$1 was locally scoped, which indeed seems to be the case. So my code should
>be written like that instead.
Wait, what?
This seems wrong -- since $1 is locally scoped, (not lexically
scoped), it -can- be technically destroyed by the param call, so you
don't want to do this, even if you can. (if param is written not to
squash $1, it's bad practice to trust in this).
However, it seems that at least in modern perls, $1 is -lexically-
scoped. That seems new. But good:
perl -Mstrict -e 'sub test { shift =~ /b(.*)/ and return $1 }; my
$str = "abababa"; print +($str =~ /((?:ba){1,2})/ and print
test($str),"\n") ? $1 : "no","\n"'
ababa
baba
(now, if while(<>) {} bashing $_ gets fixed, I'll be happy.
Surprised, but happy).
A checkbox group is how I'd certainly do it (and have done it), though
that doesn't help as much if you've got mixed values (a checkbox and a
textbox with a count, either of which, if changed, can select an
item. Yeah, in the modern world, you can use javascript for this
nonsense, but then there are mobile browsers and paranoid people).
For short (if marginally less efficient) code, why not:
my @list = map +($cgi->param($_) ? /^$prefix(\d+)$/ : ()),$cgi->param;
--
Joshua Kronengold (mneme@(io.com, labcats.org)) |\ _,,,--,,_ ,)
--^-- "Did you know, if you increment enough, you /,`.-'`' -, ;-;;'
/\\ get an extra digit?" "I knew," weeps Six. |,4- ) )-,_ ) /\
/-\\\ "We knew. But we had forgotten." '---''(_/--' (_/-'
Date: December 14, 2006
From: Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
In-reply-to:
<200612011635.44839.shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx>
Hello to everybody,
it's been almost two weeks since this quiz was posted and I neglected to post
a spoiler as I've been unfortunately distracted by other things. Thanks to
everyone who submitted me a solution for this problem.
Now let's go over the code.
On Friday 01 December 2006 16:35, Shlomi Fish wrote:
> Hi all!
>
> Well, it's been a while since we had a quiz so here's another what does
> this code do quiz:
>
> {{{{{{
> my (@list) =
> (
> grep { $cgi->param("$prefix$_") }
> map { /^${prefix}(\d+)$/ ? ($1) : () }
> $cgi->param()
> );
> }}}}}}
$cgi->param() in list context returns a list of all CGI parameter "NAME"s. The
map part matches against a regex which matches a prefix string followed by
digits. If a NAME matches the retgex the digit part is extracted, and if
doesn't, it is skipped.
The grep makes sure the $cgi->param() of the original NAME (with the prefix
back on) is true.
This was used in an HTML form where there was a checkbox with a certain prefix
for every ID:
<<<<<
<input type="checkbox" name="toggle_1" />
<input type="checkbox" name="toggle_2" />
<input type="checkbox" name="toggle_3" />
.
.
.
>>>>>
And this snippet was used to extract the IDs that were checked.
Now for some interesting input from the solvers:
1. Ronald J. Kimball suggested using the following snippet instead:
<<<<<<<<
my(@list) =
(
map { /^${prefix}(\d+)$/ && $cgi->param($_) ? $1 : () }
$cgi->param()
);
>>>>>>>>
When I said that $1 may be destroyed by the param method call, he noted that
$1 was locally scoped, which indeed seems to be the case. So my code should
be written like that instead.
2. Peter Haworth correctly detected the use that I made of the code and
suggested using a checkbox group instead:
<<<
<input type="checkbox" name="toggle" value="1" />
<input type="checkbox" name="toggle" value="2" />
<input type="checkbox" name="toggle" value="3" />
Etc.
>>>
And then just say <<< my @list = $cgi->param("toggle"); >>>.
He also suggested the following alternative code:
<<<<<<<<<
my @list=grep /\A$prefix\d+\z/ && $cgi->param($_),$cgi->param;
s/\A$prefix// for @list;
>>>>>>>>>
3. Some people suggested the following wrong codes. Can you detect why they
are wrong?
<<<<
my @list
= grep { /^$prefix(\d+)$/ && $cgi->param("$prefix$1") }
$cgi->param();
>>>>
<<<<
my @list = map { $cgi->param( $_ ) }
grep { /^$prefix(?:\d+)?$/ }
$cgi->param();
>>>>
<<<<
my @list = grep { /^${prefix}(\d+)$/ && $cgi->param($_) } $cgi->param();
>>>>
4. Many people wrongly believed that @list returns the NAMES along with the
prefix instead of just the IDs.
--------------
Well, this was fun quiz, and I enjoyed reading your answers. Those who sent a
reply to me in private may be interested in forwarding it to the list.
If anyone has an idea for a quiz, he or she should feel free to send it to the
list.
Regards,
Shlomi Fish
---------------------------------------------------------------------
Shlomi Fish shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx
Homepage: http://www.shlomifish.org/
Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.
Date: December 13, 2006
From: Ronald J Kimball <rjk-Sv9uFpfxDRWsTnJN9+BGXg@xxxxxxxxxxxxxxxx>
In-reply-to:
<200612011635.44839.shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx>
This was my answer:
--
It returns the numbers for which the corresponding parameters have a true
value.
This seems like a simpler way to do it:
my(@list) =
(
map { /^${prefix}(\d+)$/ && $cgi->param($_) ? $1 : () }
$cgi->param()
);
I guess it was used for handling a web form with a group of related fields,
where the user may enter a value for only some of the fields. For example,
a list of files to upload.
--
Shlomi responded, "Actually, it was a number of checkboxes with the same
prefix for their name attribute in my case."
Which would be another example of what I guessed. :)
Ronald
Date: December 13, 2006
From: Charles Abney <cabney-XkckGZ689+c@xxxxxxxxxxxxxxxx>
I'm getting failed sends of my list submissions. Methinks those should stay with the list maintainer, or?
Date: December 13, 2006
From: Charles Abney <cabney-XkckGZ689+c@xxxxxxxxxxxxxxxx>
In-reply-to:
<86lklb1mpq.fsf-QQWfiD5J9rlvIiBbVGLYw0EOCMrvLtNR@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <20061214084046.d03dd17d.rcook@xxxxxxxxxxx> <86lklb1mpq.fsf@xxxxxxxxxxxxxxxxxxx>
Randal L. Schwartz wrote:
> my @addressline = grep { /^addressline/ and defined param($_) } param();
>
> That's how I'd do that instead. To use them, you're gonna need to go
> back to the full $prefix form anyway!
yabut... then (to use my example earlier) you'll also grab the values
for 'radio-googoo' and 'radio-gaga', which are functionally different
from radio01 - radio20
Date: December 13, 2006
From: Charles Abney <cabney-XkckGZ689+c@xxxxxxxxxxxxxxxx>
In-reply-to:
<20061214084046.d03dd17d.rcook-iMDvLBO0GCq6c6uEtOJ/EA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <20061214084046.d03dd17d.rcook@xxxxxxxxxxx>
Owen wrote:
> On Fri, 1 Dec 2006 16:35:44 +0200
> Shlomi Fish <shlomif-ik1l9ssToec+JF/nGntIXQ@xxxxxxxxxxxxxxxx> wrote:
>> my (@list) =
>> (
>> grep { $cgi->param("$prefix$_") }
>> map { /^${prefix}(\d+)$/ ? ($1) : () }
>> $cgi->param()
>> );
> I have waited 60 hours and more now. Just wondering if there was a follow up
> to the message because like the friend above, I too have problems
> understanding what was going on!
Best I can get is that it'll grab the values of a subset of parameters
submitted in a request. Say you have 20 radio groups named radio01,
radio02, etc. Give $prefix a value of "radio", and bob's your uncle.
Date: December 13, 2006
From: merlyn-DiZw3cqpylQkmLvzuZlaBw@xxxxxxxxxxxxxxxx (Randal L. Schwartz)
In-reply-to:
<20061214084046.d03dd17d.rcook-iMDvLBO0GCq6c6uEtOJ/EA@xxxxxxxxxxxxxxxx>
References:
<200612011635.44839.shlomif@xxxxxxxxxxx> <20061214084046.d03dd17d.rcook@xxxxxxxxxxx>
>>>>> "Owen" == Owen <rcook-iMDvLBO0GCq6c6uEtOJ/EA@xxxxxxxxxxxxxxxx> writes:
>> my (@list) =
>> (
>> grep { $cgi->param("$prefix$_") }
>> map { /^${prefix}(\d+)$/ ? ($1) : () }
>> $cgi->param()
>> );
Owen> I have waited 60 hours and more now. Just wondering if there was a
Owen> follow up to the message because like the friend above, I too have
Owen> problems understanding what was going on!
Given a $prefix like "addressline", @list will contain a list of all numbers
tailed from elements like "addressline1" and "addressline37" that contain
non-false form values (1 and 37 in this case).
I don't think that'd be as useful as hand coding this instead:
my @addressline = grep { /^addressline/ and defined param($_) } param();
That's how I'd do that instead. To use them, you're gonna need to go
back to the full $prefix form anyway!
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn-DiZw3cqpylQkmLvzuZlaBw@xxxxxxxxxxxxxxxx>
<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!