Altering values by reference

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default Re: Altering values by reference

    Dela Lovecraft wrote:
    > Is there a way of altering a variable sent as a reference to a
    > subroutine in Perl *without* using a return value?
    <snip>
    > Suppose I had a sub doSomething which added 10 to a value. Assuming
    > I sent it by reference, it could like something like this:
    >
    > sub doSomething
    > {
    > my $reference = shift;
    > my $value = $$reference;
    > return ($value + 10);
    > }
    >
    > And it would be called:
    > my $x = 1;
    > my $y = doSomething(\$x);
    >
    > No problem. But is there a way I could call the sub such that the
    > value of $x could be altered in situ without returning a value,
    > even over different packages? Something like:
    >
    > my $x = 1;
    > myOtherPackage::doSomething(\$x); #such that $x now equals 11
    sub doSomething { ${$_[0]} += 10 }

    / Gunnar

    --
    Gunnar Hjalmarsson
    Email: [url]http://www.gunnar.cc/cgi-bin/contact.pl[/url]

    Gunnar Hjalmarsson Guest

  2. Similar Questions and Discussions

    1. Macintosh Browsers Altering Checkbox Values
      We have a form that contains a dozen or so checkboxes that we are using in an HTML email. When the values are being passed to our Cold Fusion...
    2. Altering Page Dimensions
      Program: INdesign CS Premium Project: 12 Page CD Booklet (Concertina Fold) (2X spreads of 6 pages each, print as pairs) PROBLEM: My printer...
    3. altering text path
      IS there a way of transforming a text path that leaves the characters unaltered? When I scale a path the characters scale and when I reflect it...
    4. Missing CODEGEN values from DataSet Web Reference and Properties are not updated
      I've created a web service that has a project reference to a library that contains a strongly typed dataset. The web service has a function that...
    5. Altering a Record In a Form
      On Sat, 5 Jul 2003 15:35:21 -0700, "Jen" <jen@noemail.com> wrote: If you have a "Bound" combo box, *that is precisely what it's intended to...
  3. #2

    Default Re: Altering values by reference

    Dela Lovecraft wrote:
    > Dear All,
    >
    > I was having a discussion with a die-hard Pascal programmer yesterday, and a
    > point was raised I couldn't answer, and I said I would try and find the
    > answer for him. Is there a way of altering a variable sent as a reference
    > to a subroutine in Perl *without* using a return value? As I recall, in
    > Pascal, you send to a function using either the value or declaring it as
    > var, in which case in can get altered in the procedure:
    >
    > procedure myProc(x : Integer; var y : Integer)
    >
    > Whatever is sent to the procedure as x remains unchanged, but anything which
    > happens to y (because of the var keyword) is changed in the original
    > variable. I think (sorry of the syntax for Pascal is off, but it has been a
    > long time.) Is such a thing possible in Perl?
    Parameters in Perl are always passed by reference (That is, the
    references reside inside the magical array @_). "Pass by value" only
    happens when you take things out of @_ (e.g. by calling shift without
    arguments). If you access @_ directly you get the desired behavior.

    some code: (untested)

    sub inc {
    $_[0]++
    }

    my $i = 0;

    inc($i);

    print $i

    shows that $i has been modified inside the subroutine inc.

    bye
    malte


    Malte Ubl Guest

  4. #3

    Default Altering values by reference

    Dear All,

    I was having a discussion with a die-hard Pascal programmer yesterday, and a
    point was raised I couldn't answer, and I said I would try and find the
    answer for him. Is there a way of altering a variable sent as a reference
    to a subroutine in Perl *without* using a return value? As I recall, in
    Pascal, you send to a function using either the value or declaring it as
    var, in which case in can get altered in the procedure:

    procedure myProc(x : Integer; var y : Integer)

    Whatever is sent to the procedure as x remains unchanged, but anything which
    happens to y (because of the var keyword) is changed in the original
    variable. I think (sorry of the syntax for Pascal is off, but it has been a
    long time.) Is such a thing possible in Perl?

    Suppose I had a sub doSomething which added 10 to a value. Assuming I sent
    it by reference, it could like something like this:

    sub doSomething
    {
    my $reference = shift;
    my $value = $$reference;
    return ($value + 10);
    }

    And it would be called:
    my $x = 1;
    my $y = doSomething(\$x);

    No problem. But is there a way I could call the sub such that the value of
    $x could be altered in situ without returning a value, even over different
    packages? Something like:

    my $x = 1;
    myOtherPackage::doSomething(\$x); #such that $x now equals 11


    Any help would be really appreciated.


    Dela



    Dela Lovecraft Guest

  5. #4

    Default Re: Altering values by reference

    Dela Lovecraft <dlovecraft@remove.this.to.emai.lme.breathe.com> writes:
    > sub doSomething
    > {
    > my $reference = shift;
    > my $value = $$reference;
    > return ($value + 10);
    > }
    >
    > And it would be called:
    > my $x = 1;
    > my $y = doSomething(\$x);
    >
    > No problem. But is there a way I could call the sub such that the value of
    > $x could be altered in situ without returning a value, even over different
    > packages?
    packages are irrelevant unless you are using _symbolic_ references.

    Something like:
    > my $x = 1;
    > myOtherPackage::doSomething(\$x); #such that $x now equals 11
    No problem

    package myOtherPackage;
    sub doSomething
    {
    my $reference = shift;
    $$reference += 10;
    }

    I you dont like putting the \ in the call to doSomething() you can put
    it in a prototype instead. Or you can manipulate $_[0] directly rather
    than using shift.

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley Guest

  6. #5

    Default Re: Altering values by reference

    Dela Lovecraft <dlovecraft@remove.this.to.emai.lme.breathe.com> wrote:
    > Is there a way of altering a variable sent as a reference
    > to a subroutine in Perl *without* using a return value?

    Yes.

    In fact, you can alter a variable even if it is NOT a reference.

    (as long as it IS an "lvalue".)


    [snip: call-by-value vs. call-by-reference]

    > Is such a thing possible in Perl?

    Yes.

    > Suppose I had a sub

    Then you would surely read the docs for subroutines (perlsub.pod)
    and come across this:

    Because the assignment copies the values, this also has the effect
    of turning call-by-reference into call-by-value. Otherwise a
    function is free to do in-place modifications of C<@_> and change
    its caller's values.

    and you would have already known the answer to your question. :-)



    To get call-by-reference (the default) in Perl:

    by_ref($x);
    sub by_ref { $_[0] += 10 }

    To get (the effect of) call-by-value in Perl:

    by_val($x);
    sub by_val { my $num = $_[0]; $num += 10 } # make copy, operate on copy


    Neither of them use what is termed a "reference" in Perl (ie. perlref.pod).


    --
    Tad McClellan SGML consulting
    [email]tadmc@augustmail.com[/email] Perl programming
    Fort Worth, Texas
    Tad McClellan Guest

  7. #6

    Default Re: Altering values by reference

    On Thu, 26 Jun 2003 12:42:19 +0200
    Malte Ubl <ubl@schaffhausen.de> wrote:
    >Dela Lovecraft wrote:
    >Parameters in Perl are always passed by reference (That is, the
    >references reside inside the magical array @_). "Pass by value" only
    >happens when you take things out of @_ (e.g. by calling shift without
    >arguments). If you access @_ directly you get the desired behavior.
    Now i have another question are both these same

    sub doSomething{
    my ($arg1, $arg2) = @_;
    ..
    }

    sub doSomething{
    my $arg1 = shift;
    my $arg2 = shift;
    ..
    }


    Since you (and perldoc perlsub) say that the @_ contains aliases to scalar parameters and when you shift it they become values. Iam slightly confused. Im my first assignment am I assigning the references then ? I have code like these that has been working properly.

    Thanks in advance

    Regards,
    Thens
    Thens Guest

  8. #7

    Default Re: Altering values by reference

    To al that answered.

    Thanks very much. I knew it was possible somehow, but I couldn't quite get
    my head round it. I don't do a vast amount of coding, so was a bit lost.

    Thanks again,


    Dela

    Dela Lovecraft Guest

  9. #8

    Default Re: Altering values by reference

    Thens <thens@nospam.com> wrote:
    > are both these same
    >
    > sub doSomething{
    > my ($arg1, $arg2) = @_;
    > ..
    > }
    >
    > sub doSomething{
    > my $arg1 = shift;
    > my $arg2 = shift;
    > ..
    > }

    Yes, with regard to call-by-value vs. call-by-reference.

    No, with respect to their effects on the contents of @_.


    --
    Tad McClellan SGML consulting
    [email]tadmc@augustmail.com[/email] Perl programming
    Fort Worth, Texas
    Tad McClellan Guest

  10. #9

    Default Re: Altering values by reference

    Dela Lovecraft wrote:
    >Is there a way of altering a variable sent as a reference
    >to a subroutine in Perl *without* using a return value?
    Yes. The values in @_° are aliases to the original values. So modify
    $_[0] directly, and you'll modify the first parameter; etc.

    For example:

    sub inc {
    $_[0]++;
    }

    my $x = 3;
    inc $x;
    print $x; # prints "4"

    It's only when assigning the contents out of @_ to your local (usually
    lexical) variables, that you actually make a copy.

    sub foo {
    my $x = shift; # copy
    my($y, $z) = @_; # copy
    $x++; $y++; $z++;
    # The original parameters are still unaltered
    }

    --
    Bart.
    Bart Lateur Guest

  11. #10

    Default Re: Altering values by reference

    Thens <thens@nospam.com> writes:
    > sub doSomething{
    > my ($arg1, $arg2) = @_;
    > ..
    > }
    >
    > sub doSomething{
    > my $arg1 = shift;
    > my $arg2 = shift;
    > ..
    > }
    > Since you (and perldoc perlsub) say that the @_ contains aliases
    > to scalar parameters and when you shift it they become values.
    No, they remain aliases (lvalues) even when you shift. It is when you
    evaluate then in an rvalue context (i.e. a context like that found on
    RHS of an assignment) they become (r)values.

    sub one {
    # Due to a mis-feature of the Perl compiler this genreates spurious
    # compile-time error:
    # Can't modify shift in postincrement (++)
    # If I try to do:
    # shift()++;
    # Actually you can, but you have to fool the compiler in to not noticing.
    $_++ for shift;
    }

    sub two {
    $_[0]++;
    }

    my $q = 1;
    one($q);
    print "After one(): $q\n";
    two($q);
    print "After two(): $q\n";
    __END__
    After one(): 2
    After two(): 3

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley Guest

  12. #11

    Default Re: Altering values by reference

    Brian McCauley wrote:
    > $_++ for shift;
    hehe :)

    Malte Ubl Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139