Re: Help with understanding references to subroutines

Discussion in 'Perl Misc' started by Rainer Weikusat, Jan 4, 2014.

  1. Dave Stratford <> writes:

    [...]

    > 4. Two ways to create a reference to a subroutine:
    >
    > a) Start with a subroutine
    >
    > sub foo { return 'bar'; }
    > my $r_sub = \&foo;
    >
    >
    > b) Directly create a reference to an anonymous subroutine
    >
    > my $r_sub = sub { return 'bar'; };
    >
    > In either case to call it, just type
    >
    > &$r_sub();


    Calling a subroutine via & has the two 'special effects' of bypassing
    any prototype checking and reusing the current @_ for its
    arguments. This is mostly useful for 'call-forwarding'. Assuming that
    $r_sub contains a sub reference, it can also be invoked as

    $r_sub->(arg0, arg1, ...)

    [...]


    [...]

    > When I run it, I get exactly what I want to get, but it seems to me to be
    > an excessively awkward way to decide which of two subroutines you want to
    > call.
    >
    > What is the purpose of the subroutine reference?


    Contrived example:

    -------------
    my %ops = (
    '+' => sub { $_[0] + $_[1]},
    '-' => sub { $_[0] - $_[1]},
    '*' => sub { $_[0] * $_[1]},
    '/' => sub { $_[0] / $_[1]},
    '^' => sub { $_[0] ** $_[1]});

    sub calc
    {
    my ($op, $a, $b) = @_;
    printf("The result is %f\n", $op->($a, $b));
    }

    my $in;

    while (1) {
    print("Enter a term: ");

    $in = <STDIN>;
    $in // last;

    $in =~ /^\s*(\d+)\s*([-+^*\/])\s*(\d+)\s*$/ or do {
    print STDERR ("\tWTF??\n\n");
    next;
    };

    calc($ops{$2}, $1, $3);
    }

    print("\n");
    -------------

    This reads terms of the form

    <integer> <operator> <integer>

    (operators are +, -, *, / an ^) from stdin, computes the result and
    prints it.
    Rainer Weikusat, Jan 4, 2014
    #1
    1. Advertising

  2. Rainer Weikusat <> writes:

    [...]

    > $in =~ /^\s*(\d+)\s*([-+^*\/])\s*(\d+)\s*$/ or do {
    > print STDERR ("\tWTF??\n\n");
    > next;
    > };
    >
    > calc($ops{$2}, $1, $3);


    Additional remark: Calling a function like this is usually not a good
    idea because the next successful regex-match will change the values of
    $1, $2 and $3, thus possibly changing the arguments to the function as
    unintended side effect (in case the called subroutine accesses its
    arguments via @_ instead of copying them into my-variables).
    Rainer Weikusat, Jan 4, 2014
    #2
    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. Ketema

    References Subroutines and Arrays

    Ketema, Mar 5, 2004, in forum: Perl Misc
    Replies:
    2
    Views:
    140
  3. Peter J. Holzer
    Replies:
    1
    Views:
    82
    Rainer Weikusat
    Jan 7, 2014
  4. Jürgen Exner
    Replies:
    9
    Views:
    91
    Charlton Wilbur
    Jan 13, 2014
  5. George Mpouras
    Replies:
    0
    Views:
    71
    George Mpouras
    Jan 5, 2014
Loading...

Share This Page