Subroutines and '&'

Discussion in 'Perl Misc' started by Bill H, Aug 7, 2007.

  1. Bill H

    Bill H Guest

    I have always called my subroutines with an '&', Example:

    &something;

    sub something
    {
    return;
    }

    But I see in the perlfaq that the '&' isnt used. Is there any reason I
    should / should't be using the '&' or does it just not make a
    difference?

    Bill H
    Bill H, Aug 7, 2007
    #1
    1. Advertising

  2. Bill H wrote:
    > I have always called my subroutines with an '&', Example:
    >
    > &something;
    >
    > sub something
    > {
    > return;
    > }
    >
    > But I see in the perlfaq that the '&' isnt used. Is there any reason I
    > should / should't be using the '&' or does it just not make a
    > difference?


    perldoc -q "&foo"

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Aug 7, 2007
    #2
    1. Advertising

  3. >>>>> "Sherm" == Sherm Pendley <> writes:

    Sherm> It *does* make a difference - if you don't know or understand what that
    Sherm> difference is, or you don't specifically want the behavior specified by
    Sherm> the &, you shouldn't use it.

    Or, for the opposite point of view, if you have:

    sub log { print STDERR localtime() . ": @_\n" }

    then you better darn well invoke it as:

    &log("my message");

    and *not*:

    log("my message"); # invokes built-in logarithm function

    And until you know all the perl built-ins, you should use &. And this
    is what we teach in Learning Perl.

    Please don't be so quick to dismiss the value of the leading &.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
    Randal L. Schwartz, Aug 7, 2007
    #3
  4. >>>>> "~greg" == ~greg <> writes:

    ~greg> It is still required,
    ~greg> but only when dealing with references (I think)

    Or when dealing with a subroutine that is the same name as a built-in.
    See my other post.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
    Randal L. Schwartz, Aug 7, 2007
    #4
  5. Bill H

    Paul Lalli Guest

    On Aug 7, 2:32 pm, (Randal L. Schwartz) wrote:

    > Or, for the opposite point of view, if you have:
    >
    > sub log { print STDERR localtime() . ": @_\n" }
    >
    > then you better darn well invoke it as:
    >
    > &log("my message");
    >
    > and *not*:
    >
    > log("my message"); # invokes built-in logarithm function
    >
    > And until you know all the perl built-ins, you should use &.


    The difference, of course, is that failing to use & when required will
    generate a pretty explicit warning, while using it when you shouldn't
    will not. That's why I generally tell my students this is the one
    tiny piece of Learning Perl that I disagree with. :-/

    Paul Lalli
    Paul Lalli, Aug 7, 2007
    #5
  6. Bill H

    Mirco Wahab Guest

    ~greg wrote:
    > It is still required,
    > but only when dealing with references (I think)


    And nonlocal context 'jumps':

    ...
    sub indirect { print "otherthing\n@_\n" };

    sub onething { goto &indirect; print "this wont show up\n" }

    onething( qw'A B C' );
    ...


    Regards

    M.
    Mirco Wahab, Aug 7, 2007
    #6
  7. Randal L. Schwartz wrote:
    >>>>>> "Sherm" == Sherm Pendley <> writes:

    >
    > Sherm> It *does* make a difference - if you don't know or understand what that
    > Sherm> difference is, or you don't specifically want the behavior specified by
    > Sherm> the &, you shouldn't use it.
    >
    > Or, for the opposite point of view, if you have:
    >
    > sub log { print STDERR localtime() . ": @_\n" }
    >
    > then you better darn well invoke it as:
    >
    > &log("my message");
    >
    > and *not*:
    >
    > log("my message"); # invokes built-in logarithm function
    >
    > And until you know all the perl built-ins, you should use &. And this
    > is what we teach in Learning Perl.
    >
    > Please don't be so quick to dismiss the value of the leading &.


    Fortunately the syntax highlighting in my editor of choice allows me to
    distinguish between built-in functions and user defined subroutines.

    :)


    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Aug 7, 2007
    #7
  8. Bill H

    Guest

    On Aug 7, 2:54 pm, (Randal L. Schwartz) wrote:
    > >>>>> "~greg" == ~greg <> writes:

    >
    > ~greg> It is still required,
    > ~greg> but only when dealing with references (I think)
    >
    > Or when dealing with a subroutine that is the same name as a built-in.
    > See my other post.
    >


    In another situation, I find it most useful as well. For example, I
    typically determine what to do in a script by checking an incoming
    parameter of a form:

    my $MODE=param('Mode');
    {
    no strict;
    $MODE="GetLogin" unless $MODE; # default sub to execute
    &$MODE; # else execute this sub
    }

    This saves a lot of 'if-else' chains. Just my 2 Canadian cents.
    --
    Amer Neely
    Web Mechanic - www.webmechanic.softouch.on.ca
    , Aug 8, 2007
    #8
  9. Bill H

    Paul Lalli Guest

    On Aug 8, 5:05 am, wrote:
    > I
    > typically determine what to do in a script by checking an incoming
    > parameter of a form:
    >
    > my $MODE=param('Mode');
    > {
    > no strict;
    > $MODE="GetLogin" unless $MODE; # default sub to execute
    > &$MODE; # else execute this sub
    >
    > }
    >
    > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.


    It's also a rather absurdly large security whole. You have no way of
    knowing what that parameter is. You are making the assumption that
    the only way to contact your CGI script is via your form. This is
    incorrect. A user can contact your CGI script without ever going near
    your form.

    You are allowing your users to call any subroutine in your program.

    Paul Lalli
    Paul Lalli, Aug 8, 2007
    #9
  10. Bill H

    -berlin.de Guest

    John W. Krahn <> wrote in comp.lang.perl.misc:
    > Randal L. Schwartz wrote:
    > >>>>>> "Sherm" == Sherm Pendley <> writes:

    > >
    > > Sherm> It *does* make a difference - if you don't know or understand what that
    > > Sherm> difference is, or you don't specifically want the behavior specified by
    > > Sherm> the &, you shouldn't use it.
    > >
    > > Or, for the opposite point of view, if you have:
    > >
    > > sub log { print STDERR localtime() . ": @_\n" }
    > >
    > > then you better darn well invoke it as:
    > >
    > > &log("my message");
    > >
    > > and *not*:
    > >
    > > log("my message"); # invokes built-in logarithm function
    > >
    > > And until you know all the perl built-ins, you should use &. And this
    > > is what we teach in Learning Perl.
    > >
    > > Please don't be so quick to dismiss the value of the leading &.

    >
    > Fortunately the syntax highlighting in my editor of choice allows me to
    > distinguish between built-in functions and user defined subroutines.
    >
    > :)


    Ignoring the smiley for the moment, the problem with syntax highlighters
    for Perl is that they aren't reliable. They tend to let you down
    exactly in the marginal cases when you could use the help.

    What's worse, sometimes a quirk in the syntax highlighter makes people
    use non-obvious code because the highlighter can't cope with the obvious
    solution.

    Currently I'm still using vim's syntax highlighting only out of inertia.
    One of these days I'm going to switch it off for good.

    Anno
    -berlin.de, Aug 8, 2007
    #10
  11. Bill H

    -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    > On Aug 7, 2:54 pm, (Randal L. Schwartz) wrote:
    > > >>>>> "~greg" == ~greg <> writes:

    > >
    > > ~greg> It is still required,
    > > ~greg> but only when dealing with references (I think)
    > >
    > > Or when dealing with a subroutine that is the same name as a built-in.
    > > See my other post.
    > >

    >
    > In another situation, I find it most useful as well. For example, I
    > typically determine what to do in a script by checking an incoming
    > parameter of a form:
    >
    > my $MODE=param('Mode');
    > {
    > no strict;
    > $MODE="GetLogin" unless $MODE; # default sub to execute
    > &$MODE; # else execute this sub
    > }
    >
    > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.


    I don't see how it saves an "if". The "else..." comment is misleading.
    You are making sure that $MODE points to a sub, and *then* (not "else")
    you're executing it.

    That aside, your code doesn't require an ampersand in the call.
    "$MODE->()" would work just as well.

    Anno
    -berlin.de, Aug 8, 2007
    #11
  12. Bill H

    Paul Lalli Guest

    On Aug 8, 6:50 am, -berlin.de wrote:
    > <> wrote in comp.lang.perl.misc:
    > > my $MODE=param('Mode');
    > > {
    > > no strict;
    > > $MODE="GetLogin" unless $MODE; # default sub to execute
    > > &$MODE; # else execute this sub
    > > }

    >
    > > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.

    >
    > I don't see how it saves an "if". The "else..." comment is
    > misleading.
    > You are making sure that $MODE points to a sub, and *then*
    > (not "else") you're executing it.


    I'm assuming he meant it prevents the need for something like:
    if ($MODE eq 'Foo') {
    Foo();
    } elsif ($MODE eq 'Bar') {
    Bar();
    } else {
    GetLogin();
    }

    Really, he's talking about Symrefs here, which is not at all the same
    issue as using an & or not on a subroutine.

    Paul Lalli
    Paul Lalli, Aug 8, 2007
    #12
  13. On Wed, 08 Aug 2007 10:42:00 +0000, anno4000 wrote:

    > Ignoring the smiley for the moment, the problem with syntax highlighters
    > for Perl is that they aren't reliable. They tend to let you down
    > exactly in the marginal cases when you could use the help.
    >
    > What's worse, sometimes a quirk in the syntax highlighter makes people
    > use non-obvious code because the highlighter can't cope with the obvious
    > solution.
    >
    > Currently I'm still using vim's syntax highlighting only out of inertia.
    > One of these days I'm going to switch it off for good.


    Emacs suffers from much the same problems. F.i. quote like operators are
    not properly recognized, making me write:

    next if m'^#';

    instead of

    next if /^#/;

    In general I can live with it though.

    M4
    Martijn Lievaart, Aug 8, 2007
    #13
  14. Bill H

    -berlin.de Guest

    Paul Lalli <> wrote in comp.lang.perl.misc:
    > On Aug 8, 6:50 am, -berlin.de wrote:
    > > <> wrote in comp.lang.perl.misc:
    > > > my $MODE=param('Mode');
    > > > {
    > > > no strict;
    > > > $MODE="GetLogin" unless $MODE; # default sub to execute
    > > > &$MODE; # else execute this sub
    > > > }

    > >
    > > > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.

    > >
    > > I don't see how it saves an "if". The "else..." comment is
    > > misleading.
    > > You are making sure that $MODE points to a sub, and *then*
    > > (not "else") you're executing it.

    >
    > I'm assuming he meant it prevents the need for something like:
    > if ($MODE eq 'Foo') {
    > Foo();
    > } elsif ($MODE eq 'Bar') {
    > Bar();
    > } else {
    > GetLogin();
    > }
    >
    > Really, he's talking about Symrefs here, which is not at all the same
    > issue as using an & or not on a subroutine.


    Right, that makes sense. It would still be preferable to use a dispatch
    table (untested):

    my %func = map {
    no strict 'refs';
    ( $_ => \ &{ $_ });
    } qw( Foo Bar Baz);

    my $mode = param( 'Mode');
    ( $func{ $mode} || \ &GetLogin)->()

    That way the symrefs are restricted to the table setup where they will
    only be used with the code-determined qw( Foo Bar Baz). Whatever
    value $mode has at run time, only these functions or GetLogin will
    be called. The original code could call anything an attacker happens
    to know about.

    Anno
    -berlin.de, Aug 8, 2007
    #14
  15. >>>>> "Martijn" == Martijn Lievaart <> writes:

    Martijn> Emacs suffers from much the same problems. F.i. quote like operators are
    Martijn> not properly recognized, making me write:

    Martijn> next if m'^#';

    Martijn> instead of

    Martijn> next if /^#/;

    Martijn> In general I can live with it though.

    That's a flaw with perl-mode. cperl-mode is far better, and actively
    maintained. First thing I do with an empty .emacs file is teach it
    to replace perl mode with cperl-mode. :)

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    --
    Posted via a free Usenet account from http://www.teranews.com
    Randal L. Schwartz, Aug 8, 2007
    #15
  16. [Semi-OT] Configuring emacs (was Re: Subroutines and '&')

    On Wed, 08 Aug 2007 10:10:53 -0700, Randal L. Schwartz wrote:

    >>>>>> "Martijn" == Martijn Lievaart <> writes:

    >
    > Martijn> Emacs suffers from much the same problems. F.i. quote like
    > operators are Martijn> not properly recognized, making me write:
    >
    > Martijn> next if m'^#';
    >
    > Martijn> instead of
    >
    > Martijn> next if /^#/;
    >
    > Martijn> In general I can live with it though.
    >
    > That's a flaw with perl-mode. cperl-mode is far better, and actively
    > maintained. First thing I do with an empty .emacs file is teach it to
    > replace perl mode with cperl-mode. :)


    Can you give me the magic incantations? I'm not very fluent in emacs-lisp.

    TIA,
    M4
    Martijn Lievaart, Aug 8, 2007
    #16
  17. Bill H

    Guest

    On Aug 8, 6:39 am, Paul Lalli <> wrote:
    > On Aug 8, 5:05 am, wrote:
    >
    > > I
    > > typically determine what to do in a script by checking an incoming
    > > parameter of a form:

    >
    > > my $MODE=param('Mode');
    > > {
    > > no strict;
    > > $MODE="GetLogin" unless $MODE; # default sub to execute
    > > &$MODE; # else execute this sub

    >
    > > }

    >
    > > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.

    >
    > It's also a rather absurdly large security whole. You have no way of
    > knowing what that parameter is. You are making the assumption that
    > the only way to contact your CGI script is via your form. This is
    > incorrect. A user can contact your CGI script without ever going near
    > your form.
    >
    > You are allowing your users to call any subroutine in your program.
    >
    > Paul Lalli


    I see where that would be possible. But would a user not need to know
    the name of a subroutine in my script? My goal is to try and combine
    as many functions as possible into one script, rather than have 5 or 6
    separate scripts to maintain. Which brings up a question: if a user
    can call any subroutine in my script, what's to stop them from running
    a separate script as well?

    If there is no secure way to do this with this particular method I
    would like to know so as to fix it.

    --
    Amer Neely
    Web Mechanic - www.webmechanic.softouch.on.ca
    , Aug 8, 2007
    #17
  18. Bill H

    Guest

    On Aug 8, 6:50 am, -berlin.de wrote:
    > <> wrote in comp.lang.perl.misc:
    >
    >
    >
    > > On Aug 7, 2:54 pm, (Randal L. Schwartz) wrote:
    > > > >>>>> "~greg" == ~greg <> writes:

    >
    > > > ~greg> It is still required,
    > > > ~greg> but only when dealing with references (I think)

    >
    > > > Or when dealing with a subroutine that is the same name as a built-in.
    > > > See my other post.

    >
    > > In another situation, I find it most useful as well. For example, I
    > > typically determine what to do in a script by checking an incoming
    > > parameter of a form:

    >
    > > my $MODE=param('Mode');
    > > {
    > > no strict;
    > > $MODE="GetLogin" unless $MODE; # default sub to execute
    > > &$MODE; # else execute this sub
    > > }

    >
    > > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.

    >
    > I don't see how it saves an "if". The "else..." comment is misleading.
    > You are making sure that $MODE points to a sub, and *then* (not "else")
    > you're executing it.
    >
    > That aside, your code doesn't require an ampersand in the call.
    > "$MODE->()" would work just as well.
    >
    > Anno


    You're right - I was a little hasty with my wording. And thanks for
    the usage of $MODE sans the leading ampersand.
    --
    Amer Neely
    Web Mechanic - www.webmechanic.softouch.on.ca
    , Aug 8, 2007
    #18
  19. Bill H

    Guest

    On Aug 8, 9:55 am, "A. Sinan Unur" <> wrote:
    > wrote innews::
    >
    >
    >
    > > On Aug 7, 2:54 pm, (Randal L. Schwartz) wrote:
    > >> >>>>> "~greg" == ~greg <> writes:

    >
    > >> ~greg> It is still required,
    > >> ~greg> but only when dealing with references (I think)

    >
    > >> Or when dealing with a subroutine that is the same name as a
    > >> built-in. See my other post.

    >
    > > In another situation, I find it most useful as well. For example, I
    > > typically determine what to do in a script by checking an incoming
    > > parameter of a form:

    >
    > > my $MODE=param('Mode');
    > > {
    > > no strict;
    > > $MODE="GetLogin" unless $MODE; # default sub to execute
    > > &$MODE; # else execute this sub
    > > }

    >
    > > This saves a lot of 'if-else' chains. Just my 2 Canadian cents.

    >
    > The current exchange rate notwithstanding, not worth much, I am afraid.
    >
    > The proper way to do this allows you to check if an invalid mode was
    > provided using a lookup table.
    >
    > # untested code
    >
    > my %mode_handlers = (
    > GetLogin => \&GetLogin,
    > ...
    > );
    >
    > my $mode = param('Mode');
    >
    > my $handler;
    >
    > if ( exists $mode_handlers{ $mode } ) {
    > $handler = $mode_handlers{ $mode } ;
    >
    > }
    >
    > unless ( defined $handler ) {
    > $handler = $mode_handlers{ GetLogin };
    >
    > }
    >
    > $handler->( ... );
    >
    > __END__
    >
    > The exists guard is necessary if you are running under mod_perl or
    > Fast::CGI or any other environment where you program is expected to
    > serve multiple requests.
    >
    > Otherwise, each invalid mode request can increase the memory footprint
    > of your program.
    >
    > Sinan


    Ah, thank you for this suggestion. I will implement this in my
    scripts.
    --
    Amer Neely
    Web Mechanic - www.webmechanic.softouch.on.ca

    >
    > > --
    > > Amer Neely

    >
    > Your sig separator is incorrect: It should be dash-dash-space-newline.
    > Yours is missing a space.
    >


    Fixed now. Thanks.
    --
    Amer Neely
    Web Mechanic - www.webmechanic.softouch.on.ca
    , Aug 8, 2007
    #19
  20. Bill H

    -berlin.de Guest

    Lawrence Statton <> wrote in comp.lang.perl.misc:
    > (Randal L. Schwartz) writes:
    > > That's a flaw with perl-mode. cperl-mode is far better, and actively
    > > maintained. First thing I do with an empty .emacs file is teach it
    > > to replace perl mode with cperl-mode. :)
    > >

    >
    > I agree with the solution to that *particular* problem, but as is oft
    > said: Nothing but perl can parse Perl with absolute certainty. While
    > cperl-mode does not get nearly as confused nearly as often as
    > perl-mode did, I have succeeded in confusing its parser on occasion.
    >
    > That being said, what superior alternative does the grandparent poster
    > propose? Merely saying that the syntax-highlighter is imperfect does
    > not obviate the benefits that even a mediocre highlighter offers.


    Superiority is relative. For the moment I'm still using the highlighter
    that comes with vim though I find some of its properties annoying. The
    most significant problem is, as mentioned, the alternative of either
    looking at mis-highlighted code or using a style I wouldn't use if
    it weren't to appease the highlighter. More generally, I'm not too
    fond of the fruit-salad-like appearance of highlighted code in general.
    Most of the time I'm just ignoring the colors (and underlines, and
    italics, and what have you).

    I guess I'll switch to no syntax highlighting per default and enabling
    it from case to case when I think it would help, with some key bindings
    thrown in to switch quickly. It's a way to use a tool without it getting
    in the way, or so I hope.

    Anno
    -berlin.de, Aug 8, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ReaprZero

    References and subroutines

    ReaprZero, Dec 4, 2003, in forum: Perl
    Replies:
    1
    Views:
    443
    Gunnar Hjalmarsson
    Dec 4, 2003
  2. =?Utf-8?B?UGF1bA==?=

    Multiple Page_Load subroutines and User Controls

    =?Utf-8?B?UGF1bA==?=, Oct 26, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    636
    //Rutger Smit
    Oct 26, 2005
  3. Frank Silvermann

    memory and subroutines

    Frank Silvermann, Jun 14, 2006, in forum: C Programming
    Replies:
    4
    Views:
    321
    Frank Silvermann
    Jun 14, 2006
  4. Joseph Ellis
    Replies:
    6
    Views:
    135
    Joseph Ellis
    Jul 25, 2003
  5. Ketema

    References Subroutines and Arrays

    Ketema, Mar 5, 2004, in forum: Perl Misc
    Replies:
    2
    Views:
    139
Loading...

Share This Page