Passing literal with reference?

Discussion in 'Perl Misc' started by dorno, Jun 11, 2007.

  1. dorno

    dorno Guest

    Passing variables to a subroutine by reference is covered in depth by any
    of the books. Like this...

    myroutine(\$var1, \@array1, \%hash1);

    sub myroutine {
    my($scalar, array, hash) = @_;
    }

    All the variables get to the subroutine intact and no problem.

    But if I want to change the $scalar to a literal, like so.

    myroutine("myvariable", \@array1, \%hash1);

    It hoses the call and attaches the literal as a member of the array.

    To make it work I have to...

    my $var1 = "myvariable";
    myroutine(\$var1, \@array1, \%hash1);

    which takes it back to square one. No problem there, it works, but I was
    wondering if there is a way to pass a bare literal with other references?
    There has to be - in fact with Perl there is probably a dozen ways. But
    my trying and reading hasn't found it yet. This is one of those things
    that the more I try the behinder I get.

    Thanks any

    dorno
    dorno, Jun 11, 2007
    #1
    1. Advertising

  2. dorno

    Paul Lalli Guest

    On Jun 11, 2:03 pm, dorno <> wrote:
    > Passing variables to a subroutine by reference is
    > covered in depth by any of the books. Like this...
    >
    > myroutine(\$var1, \@array1, \%hash1);
    >
    > sub myroutine {
    > my($scalar, array, hash) = @_;


    Presumably, you meant $array and $hash. . .

    >
    > }
    >
    > All the variables get to the subroutine intact and no problem.
    >
    > But if I want to change the $scalar to a literal, like so.
    >
    > myroutine("myvariable", \@array1, \%hash1);
    >
    > It hoses the call and attaches the literal as a member of the array.
    >
    > To make it work I have to...
    >
    > my $var1 = "myvariable";
    > myroutine(\$var1, \@array1, \%hash1);
    >
    > which takes it back to square one. No problem there, it works, but I was
    > wondering if there is a way to pass a bare literal with other references?
    > There has to be - in fact with Perl there is probably a dozen ways. But
    > my trying and reading hasn't found it yet. This is one of those things
    > that the more I try the behinder I get.


    I do not believe you can create a reference to a literal, regardless
    of what you want to do with it. I have to ask.... what are you
    *trying* to do? That is, what problem are you trying to solve, the
    solution to which you've decided is to pass a reference to a literal?

    There are three usual reasons one passes a reference to a variable to
    a subroutine, rather than the actual variable itself:
    1) You wish to make changes to the variable within the subroutine, but
    don't want to be stuck with difficult-to-interpet code like
    $_[0] = 'newvalue';
    2) The variable is a hash or array, and so will be "flattened" into @_
    if it's passed directly, rendering you unable to use the actual hash/
    array's values.
    3) For efficiency, so you don't have to make a copy of a huge value
    every time you call the subroutine.

    In this case, (1) doesn't apply because you can't "change" a literal
    anyway. (2) doesn't apply, because you're talking about a scalar
    value. So the only thing I can think is that you're trying to gain an
    imperceptable efficiency improvement by avoiding the copy of the
    string. Is that correct?

    Paul Lalli
    Paul Lalli, Jun 11, 2007
    #2
    1. Advertising

  3. dorno

    Paul Lalli Guest

    On Jun 11, 2:03 pm, dorno <> wrote:
    > Passing variables to a subroutine by reference is covered in depth by any
    > of the books. Like this...
    >
    > myroutine(\$var1, \@array1, \%hash1);
    >
    > sub myroutine {
    > my($scalar, array, hash) = @_;
    >
    > }
    >
    > All the variables get to the subroutine intact and no problem.
    >
    > But if I want to change the $scalar to a literal, like so.
    >
    > myroutine("myvariable", \@array1, \%hash1);
    >
    > It hoses the call and attaches the literal as a member of the array.


    I should have also asked: What do you mean by this? How is the call
    "hosed"? How is it "attached as a member of the array"? If this is
    your call, and your subroutine still starts out as:
    my ($scalar, $array, $hash) = @_;
    then $scalar has the value "myvariable", $array has a reference to
    @array1, and $hash has a reference to $hash1.

    What is the problem with this example?

    Paul Lalli
    Paul Lalli, Jun 11, 2007
    #3
  4. dorno

    dorno Guest

    >
    > Presumably, you meant $array and $hash. . .


    Yep. A typo on my part. Comes from recreating a problem on my machine
    at the office that is really happening on my PC at home.

    >
    > I do not believe you can create a reference to a literal, regardless
    > of what you want to do with it. I have to ask.... what are you
    > *trying* to do? That is, what problem are you trying to solve, the
    > solution to which you've decided is to pass a reference to a literal?


    I had a feeling that a literal couldn't be referenced. But... Perl has so
    many ways to do stuff that I never imagined could be done that I was
    hoping.

    Anyway, if I can make my request somewhat more clear.

    Passing \$var, \@array and \%hash keeps the entire batch from being
    flattened. Works fine and they come out in the subroutine seperate and
    ready to go.

    But sometimes, instead of $var, I just want to pass a literal instead of
    initalizing a variable and then passing that. In that case, the whole
    batch is partially "flattened" with "literal" becoming part of whatever
    is next in the parameter string, in this case @array. It isn't a show
    stopper but is rather an inconvenience. A lot of times one of my calls
    has multiple scalars and a single hash or array and the parameters never
    change. So I either have to suck them out of the array they have been
    flattened into, or build a my $var1, my $var2, etc and pass them that way.
    Or put the scalars into an array and pass that properly.

    The other problem is that if I code the subroutine to handle a referenced
    set of parameters, a flattening of the parameters blows the code Unless I
    test and handle both (or three, or four...) cases in which case the
    handling routine usually would become more complex than the subroutine
    itself.

    > value. So the only thing I can think is that you're trying to gain an
    > imperceptable efficiency improvement by avoiding the copy of the
    > string. Is that correct?
    >


    Not really efficiency in runtime, rather efficiency in reading the code
    later. A glance at callroutine('Swords','Short','Bronze','100');
    is easier to grasp than looking at
    callroutine(\$table,\$size,\$type,\cost); then scrolling up to the
    variable list and checking out what each parameter is supposed to be.

    Actually, it is more along the lines of even though I have been using Perl for
    several years in a simplistic mode (i.e. enough to make Linux work), I am
    trying to actually learn how to code in Perl properly.

    Thanks
    dorno
    dorno, Jun 11, 2007
    #4
  5. dorno

    Paul Lalli Guest

    On Jun 11, 3:37 pm, dorno <> wrote:

    > Anyway, if I can make my request somewhat more clear.
    >
    > Passing \$var, \@array and \%hash keeps the entire batch from being
    > flattened. Works fine and they come out in the subroutine seperate
    > and ready to go.
    >
    > But sometimes, instead of $var, I just want to pass a literal
    > instead of initalizing a variable and then passing that. In that
    > case, the whole batch is partially "flattened" with "literal"
    > becoming part of whatever is next in the parameter string, in this
    > case @array.


    No, it really really doesn't. Can you show an example where you think
    this is happening? Here's my counter example:
    $ perl -le'
    sub myroutine {
    my ($s, $a, $h) = @_;
    print "Scalar: $s";
    print "Array: @$a";
    print "Hash: ", join (", ", map { "$_ => $h->{$_}" } keys %$h);
    }

    my @a = (1..5);
    my %h = (a => 1, b => 2, c => 3, d => 4, e => 5);
    myroutine("string", \@a, \%h);
    '
    Scalar: string
    Array: 1 2 3 4 5
    Hash: e => 5, c => 3, a => 1, b => 2, d => 4

    Paul Lalli
    Paul Lalli, Jun 11, 2007
    #5
  6. Paul Lalli wrote:
    > I do not believe you can create a reference to a literal, regardless
    > of what you want to do with it.


    Why do you say that? The code below prints "myvariable" just as I would
    have expected:

    sub myroutine {
    my $ref = shift;
    print $$ref;
    }

    myroutine( \'myvariable' );

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jun 11, 2007
    #6
  7. dorno

    Paul Lalli Guest

    On Jun 11, 4:04 pm, Gunnar Hjalmarsson <> wrote:
    > Paul Lalli wrote:
    > > I do not believe you can create a reference to a literal, regardless
    > > of what you want to do with it.

    >
    > Why do you say that? The code below prints "myvariable" just as I would
    > have expected:
    >
    > sub myroutine {
    > my $ref = shift;
    > print $$ref;
    > }
    >
    > myroutine( \'myvariable' );


    ..... and I stand humbly corrected.

    Thanks, Gunnar.

    Paul Lalli
    Paul Lalli, Jun 11, 2007
    #7
  8. dorno

    Dr.Ruud Guest

    dorno schreef:

    > Passing variables to a subroutine by reference is covered in depth by
    > any of the books. Like this...
    >
    > myroutine(\$var1, \@array1, \%hash1);


    The \$var1 is somewhat exceptional, normally you just do

    myroutine( $var1, \@array1, \%hash1);



    For example:

    $ perl -Mstrict -wle'
    sub f {$_[0] = reverse $_[0]}
    my $x = q(abc);
    f $x; # changes $x
    print $x;
    f q{xyz};
    '
    cba
    Modification of a read-only value attempted at -e line 2.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jun 11, 2007
    #8
  9. dorno

    Paul Lalli Guest

    On Jun 11, 4:26 pm, dorno <> wrote:
    > > Why do you say that? The code below prints "myvariable" just as I would
    > > have expected:

    >
    > > sub myroutine {
    > > my $ref = shift;
    > > print $$ref;
    > > }
    > > }
    > > myroutine( \'myvariable' );

    >
    > That did it.
    >
    > My problem was that I was always using double quotes,
    > myroutine(\"myvariable");


    There is no difference in this case between single and double quotes.
    They do the exact same thing. To illustrate:
    #!/usr/bin/env perl
    use strict;
    use warnings;
    myroutine(\'foobar');
    myroutine(\"foobar");
    sub myroutine {
    my $ref = shift;
    print $$ref . "\n";
    }
    __END__
    foobar
    foobar

    > I didn't think to try single quotes, but...
    > The Programming Perl, Perl Cookbook, and others all use double
    > quotes in their examples. Not as an example of referencing a
    > literal, but as a way to pass a literal.


    Do you understand the difference between double and single quotes?
    Double quotes interpolate variables and character escapes. Single
    quotes do not. That's it.

    > Now that I know the answer, I still have not found an example
    > in all my Perl books. Apparently passing a literal reference
    > in a mixed string of parameters is not done by Perl gurus.


    It's not done for the reason you keep trying to do, because as I'm now
    stating for the third time in this thread, the problem you keep trying
    to solve does not exist. Passing a literal directly into a subroutine
    does not cause it to magically get attached to any subsequent value
    passed in. You still have not showed any example of code where you
    think this is happening.

    Paul Lalli
    Paul Lalli, Jun 12, 2007
    #9
  10. dorno

    Dr.Ruud Guest

    dorno schreef:

    > I still have not found an example in all
    > my Perl books. Apparently passing a literal reference in a mixed
    > string of parameters is not done by Perl gurus. Or else they
    > consider it so simple that no verbage need be wasted on the topic.


    I remember there are some places in the Perl documentation where
    references to a literal are mentioned. For example as a way to define
    PI, or the size of an IO-buffer.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jun 14, 2007
    #10
  11. dorno

    Brad Baxter Guest

    On Jun 11, 3:37 pm, dorno <> wrote:
    > Anyway, if I can make my request somewhat more clear.
    >
    > Passing \$var, \@array and \%hash keeps the entire batch from being
    > flattened.


    No, passing references keeps hashes and arrays from being flattened.
    A scalar, be it a reference or not, will not be "flattened" any
    further.
    So just pass the darn scalar. :)

    show_me( "Hello", [ "cruel" ], { 'world' => '.' } );
    sub show_me {
    my( $scalar, $aref, $href ) = @_;
    print "$scalar, $aref->[0] ", %$href, "\n";
    }

    > The other problem is that if I code the subroutine to handle a referenced
    > set of parameters, a flattening of the parameters blows the code Unless I
    > test and handle both (or three, or four...) cases in which case the
    > handling routine usually would become more complex than the subroutine
    > itself.


    You're trying too hard. :)

    --
    Brad
    Brad Baxter, Jun 15, 2007
    #11
  12. dorno

    Mirco Wahab Guest

    Brad Baxter wrote:
    > On Jun 11, 3:37 pm, dorno <> wrote:
    >> Anyway, if I can make my request somewhat more clear.
    >>
    >> Passing \$var, \@array and \%hash keeps the entire batch from being
    >> flattened.

    >
    > No, passing references keeps hashes and arrays from being flattened.
    > A scalar, be it a reference or not, will not be "flattened" any
    > further.
    > So just pass the darn scalar. :)


    What if the "scalar" is, say 316,21 MB in size?
    Would you still send it down to subroutines 'as it is'?

    Regards

    M.
    Mirco Wahab, Jun 15, 2007
    #12
  13. Mirco Wahab <> writes:

    > What if the "scalar" is, say 316,21 MB in size?
    > Would you still send it down to subroutines 'as it is'?


    Yes, I think so.

    From 'perldoc perlsub':

    Any arguments passed in show up in the array @_. Therefore, if you
    called a function with two arguments, those would be stored in $_[0]
    and $_[1]. The array @_ is a local array, but its elements are aliases
    for the actual scalar parameters. In particular, if an element $_[0]
    is updated, the corresponding argument is updated (or an error occurs
    if it is not updatable).

    So Perl actually uses call-by-reference already. Of course the
    standard idioms copies the values to new variables.

    //Makholm
    Peter Makholm, Jun 15, 2007
    #13
  14. dorno

    Brad Baxter Guest

    On Jun 15, 9:06 am, Mirco Wahab <> wrote:
    > Brad Baxter wrote:
    > > On Jun 11, 3:37 pm, dorno <> wrote:
    > >> Anyway, if I can make my request somewhat more clear.

    >
    > >> Passing \$var, \@array and \%hash keeps the entire batch from being
    > >> flattened.

    >
    > > No, passing references keeps hashes and arrays from being flattened.
    > > A scalar, be it a reference or not, will not be "flattened" any
    > > further.
    > > So just pass the darn scalar. :)

    >
    > What if the "scalar" is, say 316,21 MB in size?
    > Would you still send it down to subroutines 'as it is'?
    >


    Would I? If I knew it would be that big, no. But the OP is,
    I think, dealing with a different conundrum, e.g., he says,

    "But sometimes, instead of $var, I just want to pass a literal instead
    of
    initalizing a variable and then passing that."

    It is unlikely that he is planning to pass a 316 MB literal.
    So I say again, just pass the darn thing. I will go out on
    a limb and venture to say that the number of times a scalar
    is passed to a subroutine vs. the number of times a reference
    to a scalar is passed is about, oh, 1_000_000_000:1

    Give or take.

    --
    Brad
    Brad Baxter, Jun 18, 2007
    #14
  15. dorno

    Uri Guttman Guest

    >>>>> "BB" == Brad Baxter <> writes:

    BB> It is unlikely that he is planning to pass a 316 MB literal.
    BB> So I say again, just pass the darn thing. I will go out on
    BB> a limb and venture to say that the number of times a scalar
    BB> is passed to a subroutine vs. the number of times a reference
    BB> to a scalar is passed is about, oh, 1_000_000_000:1

    BB> Give or take.

    ever realize that perl objects are references and are always passed to
    methods? i think that evens out the ratio a bit. and it isn't how often
    a scalar is passed around but how often large ones are passed. in one
    system of mine, i generally pass around scalar refs since that data may
    get copied from @_ and passed around even more. it makes sense to pass
    scalar refs then to keep the copying overhead to a minumum.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jun 18, 2007
    #15
  16. dorno

    Brad Baxter Guest

    On Jun 18, 12:14 am, Uri Guttman <> wrote:
    > >>>>> "BB" == Brad Baxter <> writes:

    >
    > BB> It is unlikely that he is planning to pass a 316 MB literal.
    > BB> So I say again, just pass the darn thing. I will go out on
    > BB> a limb and venture to say that the number of times a scalar
    > BB> is passed to a subroutine vs. the number of times a reference
    > BB> to a scalar is passed is about, oh, 1_000_000_000:1
    >
    > BB> Give or take.
    >
    > ever realize that perl objects are references and are always passed to
    > methods? i think that evens out the ratio a bit. and it isn't how often
    > a scalar is passed around but how often large ones are passed. in one
    > system of mine, i generally pass around scalar refs since that data may
    > get copied from @_ and passed around even more. it makes sense to pass
    > scalar refs then to keep the copying overhead to a minumum.


    Yes, I do realize that about objects, and I expected someone to
    mention it.
    However, I suspect that many more of those are references to hashes,
    arrays
    or whatnot than are references to scalars, so I don't really think it
    evens
    out the ratio much. (The "ratio" being, of course a figment for
    expression
    purposes. :)) I don't doubt for a minute that many people pass
    references
    to scalars when it makes sense to do so. But I still believe that far
    and
    away, simple scalars are passed more than anything else. I didn't
    think it
    was that debatable. :) In particular, when was the last time
    (outside of
    this thread) that you saw someone pass a literal as \"Hello, world?"

    --
    Brad
    Brad Baxter, Jun 19, 2007
    #16
  17. dorno

    Uri Guttman Guest

    >>>>> "BB" == Brad Baxter <> writes:

    BB> Yes, I do realize that about objects, and I expected someone to
    BB> mention it. However, I suspect that many more of those are
    BB> references to hashes, arrays or whatnot than are references to
    BB> scalars, so I don't really think it evens out the ratio much.
    BB> (The "ratio" being, of course a figment for expression
    BB> purposes. :)) I don't doubt for a minute that many people pass
    BB> references to scalars when it makes sense to do so. But I still
    BB> believe that far and away, simple scalars are passed more than
    BB> anything else. I didn't think it was that debatable. :) In
    BB> particular, when was the last time (outside of this thread) that
    BB> you saw someone pass a literal as \"Hello, world?"

    i have done it. not often but i did know it worked and was surprised to
    see someone here claim it didn't. the problem with references to
    literals is that the data is readonly and can blow up if the sub tries
    to modify it.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jun 19, 2007
    #17
    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. sam pal
    Replies:
    3
    Views:
    527
    E. Robert Tisdale
    Jul 16, 2003
  2. Robert Dodier
    Replies:
    5
    Views:
    833
  3. KevinSimonson

    Passing a Literal Array to a Method

    KevinSimonson, Mar 3, 2011, in forum: Java
    Replies:
    1
    Views:
    2,491
    KevinSimonson
    Mar 3, 2011
  4. Anonieko Ramos

    What's wrong with rpc-literal? Why use doc-literal?

    Anonieko Ramos, Sep 27, 2004, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    364
    Anonieko Ramos
    Sep 27, 2004
  5. Replies:
    2
    Views:
    131
Loading...

Share This Page