Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

2*pi*$r -- constant function without prototype

by ambrus (Abbot)
on May 01, 2008 at 10:04 UTC ( #683898=perlmeditation: print w/replies, xml ) Need Help??

Just a short note so you don't fall in the trap I did. Don't do this:

sub pi { 2*atan2(1,0) } $circumference = 2*pi*$r;

If the subroutine is unprototyped, that's parsed as pi(*$r). A few modules may export constants as unprototyped functions, in which case you may have to write an empty pair of parenthesis after them to avoid ambiguity. Of course, the best way might be to use constant.

Replies are listed 'Best First'.
Re: 2*pi*$r -- constant function without prototype
by ikegami (Patriarch) on May 01, 2008 at 10:27 UTC

    Omitting parens around arguments is fraught with peril. You've just encountered yet another situation where the parser gets "confused".

    It's my understanding that the constants created using constant and using functions with the empty prototype are not identical anymore, and that using constant is the recommended method.

      I thought the recommended advice was to use Readonly instead of use constant. Is this wrong, or if not, could you explain the circumstances when you should use each one?

      cheers
      why_bird
      ........
      Those are my principles. If you don't like them I have others.
      -- Groucho Marx
      .......

        Not sure if I would recommend Readonly over constant — at least some people have been bitten by its subtle peculiarities. As an example, see this thread.

        BTW, there's also Scalar::Readonly, which is directly manipulating the readonly-flag of scalars (instead of working with tied magic)...

        ___

        Update:  (...it was only a matter of time until someone would post a benchmark, so... :)

        use strict; use warnings; use Benchmark 'cmpthese'; use Readonly; use Scalar::Readonly ':all'; use constant NL => "\012"; Readonly my $NL => "\012"; my $nl = "\012"; readonly_on($nl); my $Nl = "\012"; cmpthese 2000000 => { constant => sub { my $s = "abc".NL."def".NL."ghi"; }, constant2 => sub { my $s = "abc${\NL}def${\NL}ghi"; }, Readonly => sub { my $s = "abc${NL}def${NL}ghi"; }, ScalarRO => sub { my $s = "abc${nl}def${nl}ghi"; }, scalarRW => sub { my $s = "abc${Nl}def${Nl}ghi"; }, direct => sub { my $s = "abc\012def\012ghi"; }, }; __END__ Rate Readonly constant2 scalarRW ScalarRO constant + direct Readonly 77851/s -- -84% -85% -85% -96% + -96% constant2 484262/s 522% -- -5% -5% -75% + -75% scalarRW 510204/s 555% 5% -- -0% -74% + -74% ScalarRO 511509/s 557% 6% 0% -- -74% + -74% constant 1960784/s 2419% 305% 284% 283% -- + -0% direct 1960784/s 2419% 305% 284% 283% 0% + --

        (as running the benchmark multiple times suggests, differences up to around 5% are insignificant)

        ___

        BTW, I think I remember PBP somewhere saying it's not meant to be treated as a bible...

        Perl Best Practices recommends Readonly. While constants with use constant are replaced at compile time, Readonly variables are normal variables, just set read-only.
        The problem with use constant is that the constants are actual functions which don't interpolate in strings!

        I recently needed the line feed ("\012") as constant (Note: "\n" is platform dependent!).
        Compare:

        use Readonly; Readonly $NL => "\012"; [...] print FILE "header1${NL}header2${NL}"; use constant NL => "\012"; [...] print FILE "header1" . NL . "header2" . NL;
        The speed penalty for Readonly is not meaningful in my case. However if you have large calculations which only dependent on constants, maybe inside a loop, then use constant is better because perl can optimise it at compile time.
Re: 2*pi*$r -- constant function without prototype
by amarquis (Curate) on May 01, 2008 at 13:27 UTC

    Is there some meaning to unary * that I don't know about (and couldn't find in perlop) that makes this parse this way? Or do unprototyped functions just gobble up anything that vaguely looks like a term?

    I tend to use parens zealously and have avoided learning about this kind of thing in the past, I guess it's time to head to the docs and read up.

    Edit: Good point Fletch, totally forgot about that. Thanks!

      Its the sigil for GLOBs (e.g. *STDOUT). How's the compiler supposed to know that $r didn't have a reference to a GLOB in it (somewhere else there was a my $r = \*STDOUT)?

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

[Perl 6] constant function without prototype
by John M. Dlugosz (Monsignor) on May 02, 2008 at 04:03 UTC
    I'm on a Perl 6 kick right now, and reading this thread made me reflect on these features as described in the Synopses. There is a lot "fixed" that I don't even think about much.

    In Perl 6, you can declare a constant simply by using constant instead of my. And you can declare one with or without a sigil. So you could have:

    constant π = 2*atan2(1,0);
    constant $pi ::= π;
    
    And either 2*$pi*$r or 2*π*$r are natural.

    Thing is, constant is lexical, like a read-only version of my. So how do you export one?

    You could also declare subs that act like unprototyped Perl 5 subs, or declare to take no arguments, or you can declare a 'term' directly.

    —John

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2022-09-25 12:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (116 votes). Check out past polls.

    Notices?