There was an old question in the age of APPLE II:
Write a BASIC program that prints itself.
Then, when C got popular, it became:
Write a C program that prints itself.
I wonder what the program would be like in Perl.
Will you try to solve it?
Thank you.
John Lin
Been there, done that. There are dozens of those available in the
archives of this newsgroup. Abigail won with the shortest file-length
of 0 bytes: an empty file always prints itself :-). If you want one
that actually prints something, Zenin came up with: @ARGV=$0;print<>;
There is an entire home page devoted to these programs with hundreds
(maybe thousands) of examples in many languages, including Perl:
http://www.nyx.net/~gthompso/quine.htm
P.S., if you asked this because of a homework question, I get the 'A',
not you. No, wait, Abigail and Zenin get the 'A', not me.
--
Jeff
In a current thread on this subject in the Fun With Perl list, I pointed
out that a Google search for 'Perl quine' yields 147 references. No
need to reinvent that particular wheel here.
--
(Just Another Larry) Rosler
Hewlett-Packard Laboratories
http://www.hpl.hp.com/personal/Larry_Rosler/
l...@hpl.hp.com
It has a first cousin:
open+0;print<0>
which is slightly shorter, and possibly even more obscure
> P.S., if you asked this because of a homework question, I get the 'A',
> not you. No, wait, Abigail and Zenin get the 'A', not me.
No. I am not a student. I just think learning Perl is a lot of fun. : )
Thanks for your answer.
John Lin
> open+0;print<0>
I think I may learn something from this code, so I drill it down.
Does FILEHANDLE #0 mean STDIN?
Apparently not, because the following code doesn't work.
open STDIN;print<STDIN>
I guess it is related to $0 but it is not documented. Can you explain it?
> Also see http://www.plover.com/~mjd/perl/quine.html
Ha ha, this is humorous.
John Lin
From perldoc -f open
open FILEHANDLE,MODE,LIST
open FILEHANDLE,EXPR
open FILEHANDLE
...
If EXPR is omitted, the scalar variable of the
same name as the FILEHANDLE contains the filename.
In this case the FILEHANDLE is 0, so the filename will be taken from $0.
You could take more characters and make it more obvious but less cool with:
open 0,$0;print<0>
--
Sam
Perl was designed to be a mess (though in the nicest of possible ways).
--Larry Wall
>I wonder what the program would be like in Perl.
>Will you try to solve it?
My favourite prints itself to STDERR, not STDOUT:
Create a file called /tmp/quine.pl, containing the following line:
Illegal division by zero at /tmp/quine.pl line 1.
When run, it will produce itself as output. (This even works under
Windows; put the file into \tmp\quine.pl but call it as 'perl
/tmp/quine.pl'.)
Cheers,
Philip
--
Philip Newton <nospam...@gmx.li>
If you're not part of the solution, you're part of the precipitate.
> My favorite prints itself to STDERR, not STDOUT:
> Create a file called /tmp/quine.pl, containing the following line:
>
> Illegal division by zero at /tmp/quine.pl line 1.
>
> When run, it will produce itself as output.
What astonished me was that
"This is a legal Perl program!!!".
(I noticed that the message is a run-time error.)
perl -c /tmp/quine.pl
/tmp/quine.pl syntax OK
How come? Are those bare words treated as subs (that need
to be autoloaded)? Then the error message should be:
Unquoted string "Illegal" may clash with future reserved word
And those slashes and dots... Are they legal "division",
"string concate" and "decimal point" respectively?
Which function produced the "zero"? tmp? or quine?
Oh, it is quite hard to figure out...
Thank you.
John Lin
Only relatively legal. Try running that with -w.
Try it with -w and Deparse (best done with perl5.6.0):
% perl5.6.0 -wMO=Deparse /tmp/quine.pl
Unquoted string "at" may clash with future reserved word at /tmp/quine.pl line 1.
Unquoted string "tmp" may clash with future reserved word at /tmp/quine.pl line 1.
Unquoted string "quine" may clash with future reserved word at /tmp/quine.pl line 1.
'division'->Illegal('zero'->by('at' / 'tmp' / 'quine' . 'line'->pl(1)));
/tmp/quine.pl syntax OK
Mike Guy
Philip 'Yes, that's my address' Newton <nospam...@gmx.li> wrote:
>
>My favourite prints itself to STDERR, not STDOUT:
>
>Create a file called /tmp/quine.pl, containing the following line:
>
>Illegal division by zero at /tmp/quine.pl line 1.
>
>When run, it will produce itself as output. (This even works under
>Windows; put the file into \tmp\quine.pl but call it as 'perl
>/tmp/quine.pl'.)
That reminds me of a programming contest in Cambridge, back in the
dim and distant days when computers had valves in them:
Produce the shortest piece of paper tape, which when fed into
the EDSAC II will punch out a copy of itself *reversed*.
This was won by Peter Swinnerton-Dyer with an iterative solution:
Take a random piece of paper tape from a rubbish bin.
Feed it into the computer.
Take the output, reverse it and feed it into the computer.
Take the output, reverse it and feed it into the computer.
Take the output, reverse it and feed it into the computer.
Take the output, reverse it and feed it into the computer.
Take the output, reverse it and feed it into the computer.
...
In practice this converged after about two iterations.
Mike Guy
But it does not do that.
It produces the _same output_ as the source, but it is not
the _source itself_.
Easily seen by doing s/quine\.pl/FOO/ in the program,
and running it as before.
Or, leaving the program as-is and changing the filename.
It is rather cool, nonetheless :-)
--
Tad McClellan SGML Consulting
ta...@metronet.com Perl programming
Fort Worth, Texas
>But it does not do that.
Well, yes, it was sort of cheating.
>Easily seen by doing s/quine\.pl/FOO/ in the program,
>and running it as before.
>
>Or, leaving the program as-is and changing the filename.
This happened to me, inadvertently, when I tried out the trick the first
time after having heard it from someone -- I created the file in the
current directory and called 'perl quine.pl', which failed, since there
were no slashes in the text ... so I changed the file and called it with
'perl $PWD/quine.pl'.
>It is rather cool, nonetheless :-)
That's what I though, too, when I saw it :-)
Well, that's what quine programs are supposed to do. Pseudo-quine
programs that open the source code file and print out the source are
usually considered to be cheating.
The idea is to write a program that *generates* its own source code.
Copying it from elsewhere is cute, but misses the point.
A more legitimate criticism of my program might be that it doesn't
produce its entire source code, because it depends on data that is
embedded in Perl, and it doesn't emit Perl itself as part of its
output.
>Easily seen by doing s/quine\.pl/FOO/ in the program,
>and running it as before.
``This isn't a payroll reporting program!''
``Why not?''
``Because it produces incorrect output if you do s/p/!/g on
the source code.''
Well, no duh. Of course it won't do what it is supposed to do, if you
alter the source code first. No programs will. This complaint
reminds me a little of the person who said that vi is bad becuse it
doesn't work if you put jelly in your keyboard.
Sometimes you get lucky, sometimes not.
On the #perl channel on IRC, there is a `nickometer' feature that
tells you how lame someone's nickname is. For example:
-> *purl* nickometer tchrist
*purl* the 'lame nick-o-meter' reading for tchrist is 0%
-> *purl* nickometer MyT-HaX0R
*purl* the 'lame nick-o-meter' reading for MyT-HaX0R is 99.87%, yrlnry
Now let's suppose we want to find a fixed point for this function.
-> *purl* nickometer 99.78%
*purl* the 'lame nick-o-meter' reading for 99.78% is 54%, yrlnry
-> *purl* nickometer 54%
*purl* the 'lame nick-o-meter' reading for 54% is 28%, yrlnry
-> *purl* nickometer 28%
*purl* the 'lame nick-o-meter' reading for 28% is 25%, yrlnry
-> *purl* nickometer 25%
*purl* the 'lame nick-o-meter' reading for 25% is 28%, yrlnry
Oh well; so much for that.
It turns out that the string '34%' yields a reading of 34%, and
similarly the string '%43' also yields a reading of 34%, so as I said,
you have to get lucky, because often these things don't converge at
all. I'd be a little surprised if Swinnerton-Dyer's solution produced
the *shortest* possible tape, which was what you said was asked for.
But since it seems to me that the shortest possible tape is the empty
tape, which produces an empty output, I can imagine that maybe
Swinnerton-Dyer's procedure did indeed yield the empty tape; at some
point you happen to enter a tape that produces an empty output, and
there's your fixed point.
A related puzzle is to find an 11-character string which is a fixed
point of the function
crypt('XX' . $string, "XX");
If the crypt() function is well-designed, an iterative method will not
work. About fifteen yers ago I iterated crypt() ten thousand times
just to make sure. (This took a lot longer then than it would today.)
The results were reassuringly random.