Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

AUTOLOAD, overload, and Roman numerals for Perl

by ferreira (Chaplain)
on Jun 29, 2007 at 15:04 UTC ( #624100=perlquestion: print w/replies, xml ) Need Help??

ferreira has asked for the wisdom of the Perl Monks concerning the following question:

I just released to CPAN a distribution named Acme-Roman. (It's propagating yet, so maybe you can't reach immediately from your favourite CPAN mirror.) As an Acme module, it is a simple experience to allow using roman numerals in Perl programs in a straightforward manner.
use Acme::Roman; print I + II; # III, as expected
That was done with a bit of overload, AUTOLOAD and a part which I am not satisfied with.

Some digression first. The idea came to me a long time ago from the solution to a Ruby quiz, namely

Ruby Quiz - Roman Numerals (#22)
(See the hightlighted solution at the Quiz Summary in the same page.) The trick in Ruby was done by defining strategic methods method_missing (which is kind of Perl AUTOLOAD) and const_missing. The Perl solution was quite natural, and I got to the point where
use Acme::Roman; print I() + II(); # III
worked fine. But when I left the parentheses, it only barfed at me with
$ perl -w -Ilib -MAcme::Roman -e 'my $x = I+II' Argument "II" isn't numeric in addition (+) at -e line 1. Argument "I" isn't numeric in addition (+) at -e line 1.
$ perl -w -Ilib -MAcme::Roman -e 'print I+II' Name "main::I" used only once: possible typo at -e line 1. print() on unopened filehandle I at -e line 1.
which revealed the barewords were not resolved with the provided AUTOLOAD. I learned that if I provided an empty protoype it worked. And that's how I coded -- but that kind of sucks: I need to define the prototype of 3999 subs (I .. MMMCMXCIX) to make it work. I think that's too expensive. (Who would like to play with an Acme module which is as heavy as a useful module? ;-)

The Ruby solution is helped by the availability of const_missing method functionality. The equivalent in Perl would be to overload barewords, but overload documentation says:

Barewords are not covered by overloaded string constants.

Does anyone have any suggestion to make this lazier? Or a different way to implement that?

Replies are listed 'Best First'.
Re: AUTOLOAD, overload, and Roman numerals for Perl
by ikegami (Patriarch) on Jun 29, 2007 at 15:59 UTC

    Barewords are autoquoted (BAREWORD -> 'BAREWORD'), except in two situations.
    1) If a function was already declared with that name, it will be treated as a function name.
    2) If a glob is expected (such as print's first argument), then it will be treated as a glob (BAREWORD -> *BAREWORD).

    A bareword is only treated as a function name when a function with that name has already been declared, so AUTOLOAD won't work. Autoquoting of barewords can't be overriden by overload, so overload won't help. Looks to me like you're stuck using &I/I() or a source filter.

    Note: use strict will generate an error when bareword autoquoting occurs outside of a hash index.

Re: AUTOLOAD, overload, and Roman numerals for Perl
by shmem (Chancellor) on Jun 29, 2007 at 17:57 UTC
    Heh. I would say that the only decent way to write an Acme::Roman module is in terms of Lingua::Romana::Perligata - it's to say: in latin... :-)


    _($_=" "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}
Re: AUTOLOAD, overload, and Roman numerals for Perl
by mrpeabody (Friar) on Jun 30, 2007 at 03:16 UTC
    Source filter?

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://624100]
Approved by philcrow
Front-paged by grinder
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2023-02-06 00:50 GMT
Find Nodes?
    Voting Booth?
    I prefer not to run the latest version of Perl because:

    Results (33 votes). Check out past polls.