--- David Blevins <[EMAIL PROTECTED]> wrote:
> > perl -nle 'print if !$seen{$_}++'
>
> The dash n (-n) puts the command 'print if !$seen{$_}++' in a while
> (<>) { ... } loop. So we get:
>
> while (<>) {
> print if !$seen{$_}++
> }
>
> $seen{$_}
>
> Tries to lookup the line in the hash of lines we've already seen.
>
> $seen{$_}++
>
> This is a complete guess, I can't seem to find anything like this in
> the 'Programming Perl' book.
It's just a postfix increment on the value in %seen as looked up using
$_ as the key. You've got the idea.
> It seems that if you say:
>
> $seen{$_} = 1;
>
> it causes the key to be added to the hash with the value 1, which is
> true in boolean context.
> So, if the key (line) wasn't previously seen, line"
>
> $seen{$_}
>
> might return a 0 or "false" to indicate it wasn't found. Then the
> line
>
> $seen{$_}++
>
> might take that 0/"false", increment it by one turning it to 1/"true"
> causing the key/$_/"line" to be added with a value of 1/"true". If
> the $_/"line" were already seen, it would have been added initially
> with a value 1/"true"; the ++ in this situation would just increment
> the value to 2,3,4...n, all of which are "true" values.
There you go.
> !$seen{$_}
>
> Might negate the 1/"true" return of looking up a key that previously
> existed in the hash, causing the
>
> print
>
> statement to execute, which is just short for
>
> print STDOUT $_;
Good. The leading ! makes it boolean, so it returns 1 or ''.
> So how close am I and where can I read about this?
lol -- you kind of have to look up the pieces. ;o]
Or maybe there's something in the FAQ's?
> > perl -pe '$_ x= !$seen{$_}++'
>
> This would bypass the need for the print statement, but I'm not sure
> how the '$_ x= ' in the statement works.
This is the one that tickled me most.
I parsed it in another post. ;o]
> > $seen{$_} ||= print OUT while <IN>;
>
> This is tons of fun! Dying to know the answer!
||= is an "or-equal" -- it assigns the right-hand argument to the
left-hand argument if the current value of the left-hand argument is
boolean false. "$a ||= 1" assigns 1 to $a if $a was '',0, or undef.
Otherwise it leaves it alone.
Since print returns a bool, and while <IN> assigns to $_ (which is
print()'s default), it prints the line just read and assigns 1 to
$seen{$_} if $seen{$_} had no value, but if $seen{$_} already has a
value, it just returns that in a void context -- a no-op. =o)
Then it reads the next line of <IN>.
I love Perl. =o)
Of course, writing readable code is always a good idea, but explaining
*tight* code is a great learning experience! lol!
__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]