Re: How's your Perl?
by tachyon (Chancellor) on Oct 27, 2003 at 03:08 UTC
|
# 1
my @x = ( \$_, \$_ );
# 2
sub foo { print "Agree :-)\n" }
{foo;redo}
# 4
dump()
The closure bug/feature Unusual Closure Behaviour
# 5
sub foo {
my $x if 0;
++$x;
}
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [d/l] [select] |
|
sub { my $x; $x = \$x; }
The anonymous sub is created and immediately falls out of existance because it's not passed to a scalar variable. And yet $x never disappears because its reference count is always going to be 1; it refers to itself.
It probably doesn't qualify as a static, and is pretty much useless, but it meets the definition of static that the OP gave.
Dave
"If I had my life to live over again, I'd be a plumber." -- Albert Einstein
| [reply] [d/l] [select] |
|
oops, you're right, my definition of "static" in the clarification was flawed :-)
I do mean function-scoped static like in C/C++ ofcourse
btw tachyon, your #1 solution isn't:
perl -le 'my @x = ( \$_, \$_ ); $x[0]=42; print $x[1]'
| [reply] [d/l] |
|
|
|
|
I do not think your code does what you think it does. You have two
different $x variables shown in your anonymous
subroutine, not a single one referencing itself.
| [reply] [d/l] |
|
A static variable in a subroutine context would be created only once and
hold its value between invocations. You've created a circular reference in
an uninvokable routine. Even if it weren't optimized away, of which I am
uncertain, it bears no resemblance to a static variable.
| [reply] |
|
|
|
my @x = ( \$_, \$_ );
No, that's not good enough :)
my @x = ( \$_, \$_ );
$x[0] = 5;
$x[1] == 5 or die;
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] [d/l] |
Re: How's your Perl?
by seattlejohn (Deacon) on Oct 27, 2003 at 07:10 UTC
|
# 1:
$[=1;
@x = (10);
# confirm it:
print $x[0], ",", $x[1], "\n";
$x[1]=20;
print $x[0], ",", $x[1], "\n";
$x[0]=30;
print $x[0], ",", $x[1], "\n";
| [reply] [d/l] |
|
$[=1;
Not quite what we had in mind, but a valid and creative solution ;)
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] |
Re: How's your Perl?
by BrowserUk (Patriarch) on Oct 27, 2003 at 10:13 UTC
|
- perl -e"sub t{ \@_ }; $s='this'; *x = t $s, $s; $x[0] = 'that'; print join' ',@x;"
- perl -e"foo while1" or perl -e"{foo;redo}"
-
- perl -e"$foo = [{1=>1}, 'foo']; print \$foo->{1}, \$foo->[1]; "
- ?
- ?
- ?
- ?
- ?
- ?
- perl -e"$foo = \\1; print eval(q[$$foo]), eval(q[$$foo + 0])"
- ?
- ?
- ?
- perl -e"sub STDOUT{\*STDOUT}"
- Bonus perl -e"print \undef; sub foo{} goto +foo"
| [reply] [d/l] [select] |
|
I couldn't get :foo while1" to work on my PC (Windows, perl 5.8.0).
I could get to work by rewriting it as "1while foo" or "1until!foo".
My own try involved a for loop--no dice. The best I could do was "for(;;foo){};" which is slightly too long.
| [reply] |
|
I could get to work by rewriting it as "1while foo" or "1until!foo".
That loop will stop as soon as foo() returns false. The quiz didn't specify that foo() will always return a true value, so you can't assume it.
---- I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
-- Schemer
:(){ :|:&};:
Note: All code is untested, unless otherwise stated
| [reply] [d/l] [select] |
|
1. yes
2. no and yes (perl treats while1 as one identifier)
3a. yes
8a. yes, cool, unexpected solution :-)
our official version uses a much much more obscure trick.. funny we never saw this one
Try this instead: eval(q[$$foo]) ne eval(q["$$foo"])
•Update: actually, no, the original was fine too.. even though $$foo and $$foo + 0 print differently, they don't compare numerically unequal, which is what the exercise was
11. doesn't appear to work for me..
% perl -e 'sub STDOUT{\*STDOUT} <STDOUT> eq <+STDOUT> or die'
Died at -e line 1.
12. yes, but why? :-)
•Update: fixed the "try this".. initially said "!=" instead of "ne" | [reply] [d/l] [select] |
|
D:\TEMP>perl -e"sub f{'fred'} goto +f"
Can't find label SCALAR(0x15d7c1c) at -e line 1.
D:\TEMP>perl -e"sub f{'fred'} goto(f)"
Can't find label SCALAR(0x15d7c1c) at -e line 1.
D:\TEMP>perl -e"sub f{'fred'} goto f->()"
Can't find label SCALAR(0x15d7c1c) at -e line 1.
But these do not ;^)
D:\TEMP>perl -e"sub f{'fred'} goto ~~f"
Can't find label fred at -e line 1.
D:\TEMP>perl -e"sub f{'fred'} goto ''.f"
Can't find label fred at -e line 1.
D:\TEMP>perl -e"sub f{'fred'} goto scalar f"
Can't find label fred at -e line 1.
D:\TEMP>perl -e"sub f{'fred'} goto ${\f}"
Can't find label fred at -e line 1.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!
| [reply] [d/l] [select] |
|
|
|
Re: How's your Perl?
by pg (Canon) on Oct 27, 2003 at 03:29 UTC
|
| [reply] |
|
| [reply] |
Re: How's your Perl?
by Juerd (Abbot) on Oct 27, 2003 at 08:15 UTC
|
Bonus Exercise: The code snippet 'sub foo{} goto +foo' produces an
error: "Can't find label SCALAR(0x31c70c)" (the address may vary)
Where does that ref come from? What does it point to?
Please note that this bug has been fixed in bleedperl.
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] |
Re: How's your Perl?
by talexb (Chancellor) on Oct 27, 2003 at 16:14 UTC
|
This isn't "How's your Perl?", it's "How's your ObfuPerl?" None of this is useful for someone looking to test Perl skills. But it was properly labelled as a "waste of time" .. I'm just thinking that it may put off anyone not familiar with the weird on-line Perl community.
--t. alex
Life is short: get busy!
| [reply] |
|
This isn't "How's your Perl?", it's "How's your ObfuPerl?"
Nevertheless this test is a good way to found out if you really know Perl intimately. You don't need to know all Perl to answer these questions in order to be a professional Perl coder that makes mission critical business applications, but that does not mean this test is useless.
None of this is useful for someone looking to test Perl skills. But it was properly labelled as a "waste of time"
Not just waste of time, but waste of time in our effort against sanity. We want you to break your brain cells over this. Your current lazy attitude is not really appreciated and we think you're afraid to admit you are not an [insert awesome title here].
I'm just thinking that it may put off anyone not familiar with the weird on-line Perl community.
Your inability to not understand what this is all about is probably not shared by the people who come here unbiased. They will probably read the introduction, which I quote for you here, with my emphasis added:
As part of our continuing crusade against sanity, we of #perlhelp (EFnet) have created a modest perl quiz to test for all the skills required to make the maintainance programmer voluntarily leap into the gaping chasm of madness. We hope it will reinforce everyone's appreciation of our favorite language, by itself and as a tool towards this noble goal. ;-)
I hope you understand now. We do this not for fun, but for a greater good.
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] |
Re: How's your Perl?
by tilly (Archbishop) on Oct 27, 2003 at 16:26 UTC
|
My answers without looking at existing ones...
- 1: I've seen this in chatter mentioned by tye, but the trick slips my memory at the moment. :-(
- 2: {foo;redo} # See RE: My favorite looping mechanism in Perl is:
- 3: This is actually two questions
-
My first thought was pseudohashes but pseudohashes are deprecated and IIRC removed in 5.8.0. Then it was $foo = \*bar; $$foo->[1] = $$foo->{1} = "hello" Hrm, Pseudohashes are allowed? OK then, $x = [{1=>1}, "hi"]; Your test will pass, albeit with an ugly scalar for each, but they are not accidentally the same, they are both references to the same string.
-
Trivial with overload, but I am not sure if that is breaking your rules. OK, sub bar {$bar[$_[0]]} $foo = \*bar; $bar[1]="hi";, that isn't a different idea than what I originally did for 3a, but it works. UPDATE 3 I don't know how to do this after all.
- 4: dump # So sorry, did you want solutions that aren't supposed to core dump? :-P
- 5: my $static if 0; # See Tie::Static for my opinion on this...
- 6:
Is it cheating for me to use a module but not write one?
# Reformat to one line if you want -e
use overload qq("")=>sub{"same"};
$x = bless \$foo;
$y = bless \$bar;
$$x= "x";
$$y= "x";
UPDATE You do this like so:
$x = do {local *foo}; $y = *foo; $foo = "hello";
- 7: UPDATE 2 $foo = *STDOUT{IO};
- 8: *x = \$|
- 9: This is actually two questions UPDATE Um, in the questions shouldn't q be qq everywhere? If you don't let $$foo interpolate, it shouldn't matter what is in it...
-
UPDATE 3 $foo = \$!; $!=1; UPDATE 5 Oops, this is wrong. I should test these answers a little, ya think?
- 9b
- 10
- 11: UPDATE 4 Put sub CORE'GLOBAL'glob{""} at the END of your code. Location matters, this code has to be seen by the Perl interpreter after Perl has seen some evidence that it needs to load File::Glob (which will overwrite us).
Bonus
| |
I, um, would have gotten more if I didn't have to go to work. Yeah, that's the ticket...
UPDATE Minor fixes. BTW I should add that while I am not terribly bad at this kind of trivia, I think that focussing on it is a horrible mistake.
UPDATE 2 Answered 7.
UPDATE 3 Took time out for 9a. I had been thinking about 10, but because nobody else bothers to hide their answers, I saw mtye's version already. 3b has me puzzled again (see Roy Johnson's note).
UPDATE 4 Added a solution to problem 11.
UPDATE 5 Admit my mistake in problem 9a. I think that I'll admit to not knowing stupid Perl trivia that well these days. Particularly since nobody else seems to be trying these too hard. Also note that my solution to problem 11 can't be placed in front with glob-assign without adding a semi-colon, which puts you over the character limit. | [reply] [d/l] [select] |
|
3. who cares about deprecated, they still work ;-)
3/6. overload is a module which isn't allowed (though there are ways to circumvent that), but more importantly bless is explicitly forbidden by the rules
the others look good :-)
UPDATE Re 9: it really is q, not qq. (notice the eval? :-)
UPDATE 2 As Roy Johnson pointed out, your 3b currently doesn't work (it's only a small one-char mistake though)
UPDATE 3 Your 9a doesn't work, they print differently but compare numerically equal. make sure to test your answers with perl -e '......; eval(q[$$foo]) != eval(q[0+$$foo]) or die' rather than using print, to avoid traps like these :-)
UPDATE 4 ex 11 works.. note that you can place it in front by using glob-assign
UPDATE 5 strictly speaking the semi isn't needed to make the condition true (which is the exercise), but even if you do include it it's still possible by dropping the "" from the sub
| [reply] [d/l] [select] |
|
If by a fix you mean sub bar {$bar[$_[0]]} $foo = *bar; $bar[1]="hi";, that does not work to the given spec.
Test it with print "yes" if \$foo->(1) eq \$foo->[1] and you see that it fails for me on 5.8.1. Get rid of the backslashes and it works, but the problem is that Perl's functions are pass by reference, return by value. Therefore the return of bar(1) is a new string with the same value as $bar[1], but you get something different by taking a reference to it.
| [reply] [d/l] [select] |
|
|
On your 3b, I get
Not an ARRAY reference at testit line 7.
upon trying to
printf "Value: %s\n", \$foo->[1];
| [reply] [d/l] |
|
For #4,
perl -edump
also works... :)
----
Zak
undef$/;$mmm="J\nutsu\nutss\nuts\nutst\nuts A\nutsn\nutso\nutst\nutsh\
+nutse\nutsr\nuts P\nutse\nutsr\nutsl\nuts H\nutsa\nutsc\nutsk\nutse\n
+utsr\nuts";open($DOH,"<",\$mmm);$_=$forbbiden=<$DOH>;s/\nuts//g;print
+;
| [reply] [d/l] [select] |
|
| [reply] |
|
How about an answer for #10 at 24 characters that passes strict?
use strict;
#23456789_123456789_1234
BEGIN{$'y=*x::=*y::=*::}
print "Yes\n"
if $x::y::x::y::y::x::y::x::x::y::y::y::y::x::y::y;
| |
| [reply] [d/l] |
|
|
Re: How's your Perl?
by mtve (Deacon) on Oct 27, 2003 at 17:56 UTC
|
#23456789012345678901234
$$_++for glob"'{x,y}"x16
Exercise 6 is easy. | [reply] [d/l] |
|
cool! now under strict :-)
| [reply] |
|
shouldn't N8 be:
$foo++ eq ($foo^=0)++
?
| [reply] [d/l] |
|
|
Re: How's your Perl?
by jryan (Vicar) on Oct 27, 2003 at 16:44 UTC
|
Is it just me, or is #8 undefined behaivor?
| [reply] |
|
undefined in what sense? Perl's behavior is defined by its source code, perhaps unless contradicted by docs.
UPDATE ick, I got pulled into a pointless discussion. To short-circuit it: anything that works consistently (that is, not dependent on random or OS/environment-dependent factors) in perl 5.8.* is acceptable for these exercises.
| [reply] |
|
($foo^=0)++ eq $foo++ involves an auto-increment on top of an assignment, which is undefined as far as I know.
For more discussion: Re: Incrementing a Hash Value.
| [reply] [d/l] |
|
|
Re: How's your Perl?
by Anonymous Monk on Oct 27, 2003 at 07:01 UTC
|
# 1
{
package MyTie;
require Tie::Array;
@ISA = qw/Tie::StdArray/;
sub STORE {@{$_[0]}[$_[1],$_[1]+1] = ($_[2]) x 2}
}
tie my @x, 'MyTie';
# 6
$x = \42;
$y = "$x";
| [reply] [d/l] |
|
tie my @x, 'MyTie';
For all exercises: no fork/exec/system/qx/open, no commandline options,
no user input, no modules, no tie, no bless, no %SIG.
I guess the first and most important exercise is reading.
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] |
Solutions
by xmath (Hermit) on Oct 28, 2003 at 23:43 UTC
|
Strict solutions to all exercises, base64-encoded:
1 | b3VyIEB4OyBteSAkeTsgKng9c3Vie1xAX30tPigkeSwkeSk=
| 2 | e2ZvbztyZWRvfQ==
| 3a | bXkgJGZvbyA9IFt7MSwgMX1d
| 3b | c3ViIHogOiBsdmFsdWUgeyAkOjp6WzFdIH0gbXkgJGZvbyA9ICp6
| 4 | ZHVtcDs7 or ZHVtcCgp or fn5kdW1w, etc :-)
| 5 | c3ViIGZvbyB7IG15ICR4IGlmIDA7IC4uLiB9
| 6 | b3VyICgkeCwgJHkpID0gKCp4LCBldmFsICJsb2NhbCAqeCIp
| 7 | bXkgJGZvbyA9ICpTVERPVVR7SU99
| 8 | b3VyICRmb287ICpmb28gPSBcKyskfA==
| 9a | bXkgJGZvbyA9IFwkXlM=
| 9b | cGFja2FnZSBZO291ciRmb289XDA7JFg6OmZvbz1cIiAiOypZOjo9Klg6Og==
| | or JGZvbz0iXzwoZXZhbCAxKSI= (non-strict original)
| 10 | QkVHSU57Knk6Oj0qeDo6PSQ6Onk9Kjo6fQ==
| 11 | KkNPUkU6OkdMT0JBTDo6Z2xvYj1zdWJ7fQ==
|
For the bonus exercise, see the explanation above | [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
|
Another (strict) solution for 9b:
BEGIN {$^H |= 0x30000}
$^H{'qr'} = sub {''};
my $foo = \'';
| [reply] [d/l] |
|
Another solution for E8:
KmZvbyA9IFxsb2NhbCAkMQ==
This one relies on a bug in perl.
| [reply] [d/l] |
|
I think the answer to number 2 is unnecessarily obfu. You can actually do it with while too... Perhaps it should ask without using while?
UPDATE: I'm pretty sure they shortened the number of characters since I wrote this.
| [reply] |
|
while(){foo} # 12 chars
foo while 1 # 11 chars
| [reply] [d/l] |
Re: How's your Perl?
by ambrus (Abbot) on Nov 02, 2003 at 16:47 UTC
|
I could solve 5 of them.
UPDATE: read some solutions. So you accept
mine for 3 and 4. Quiestion 10 is really trickey.
UPDATE: please someone explain why my solution to 8 works. I don't understand. Thx.
UPDATE: I still don't know how my solution to 8 works, I've found it accidentally, but I see that there's a similar solution using $^N. (And one even with $1, wow!) (The official solution which uses $| is eaasier to understand.)
| [reply] [d/l] [select] |
Re: How's your Perl?
by ccn (Vicar) on Mar 27, 2004 at 23:07 UTC
|
6 of 12
Exercise 1: Create an array @x such that changing $x[0] also sets $x[1] to the same value
$[=1;@x=();
Exercise 2: Given a pre-declared function "foo", write a code snippet that invokes it in an infinite loop; in 10 chars
{foo;redo}
Exercise 4: Dump core in 6 chars
dump()
Exercise 5: Create a static variable lexically scoped to a sub, and no wider than that. It's ok if it blows up under recursion
sub foo{my $static if 0}
Exercise 6: Create $x, $y such that $x eq $y && $$x ne $$y
$x=\1;$y="$x"
Exercise 8: Create $foo such that ($foo^=0)++ eq $foo++
*foo=*|;$|=1;
|
| [reply] [d/l] [select] |
Re: How's your Perl?
by thospel (Hermit) on Jul 02, 2005 at 19:22 UTC
|
Since it's meant for 5.8.0, I didn't yet see this
"real" solution for number 4:
%::=//
For later perls it's a bit longer (too long):
%::=0;//
update
oops, posted under the wrong node. This is meant for node How's your Perl?
20050703 Edit by ysth: moved from How's your Perl? (II). | [reply] [d/l] [select] |
|
| [reply] |
Re: How's your Perl?
by diotalevi (Canon) on Oct 28, 2003 at 18:20 UTC
|
There's a bunch of spoilers here so click readmore to read them.
| [reply] [d/l] [select] |
|
re 8: perl has a fixed evaluation order (L->R for most operators, including eq), so you can use that. That it's not officially defined/documented is ofcourse of no concern :-)
| [reply] [d/l] |
|
I've now see the answer (and its obvious) for #8 and in that rare case the evaluation order doesn't actually matter since it won't affect anything but if it were anything else then I'd have to call shenanigans on you for the trick question since you'd only be testing on the implementation and not the specified language.
| [reply] |
|
Re: How's your Perl?
by Beechbone (Friar) on Oct 28, 2003 at 18:25 UTC
|
| [reply] [d/l] |
Re: How's your Perl?
by ambrus (Abbot) on Jun 08, 2005 at 09:32 UTC
|
Here's a new solution for question 3a. This is not strict in the
sense that you have to turn off strict for the set-up code
to work. However, the actual test \$foo->[1] == \$foo->{1}
runs under strict, unlike in my original symbolic ref solution.
I think that this solution differs from all the solutions
given so far, so I submit it even though this puzzle
is now quite old.
| [reply] [d/l] [select] |
Re: How's your Perl?
by Roger (Parson) on Oct 27, 2003 at 03:27 UTC
|
Exercise 2
{foo,redo}
Exercise 4
dump;;
Or
dump()
.oO
.zZ
~~(>_<)~~
| [reply] [d/l] [select] |
|
Why the strike through your solution to Exercise 4? It was exactly what we had in mind.
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |