@_ aliasing

Discussion in 'Perl Misc' started by Matija Papec, Sep 22, 2005.

  1. Matija Papec

    Matija Papec Guest

    Is there a perl version which prints 5 in case when,
    perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'

    I was almost sure that shift() should not break the aliasing.
     
    Matija Papec, Sep 22, 2005
    #1
    1. Advertising

  2. Matija Papec wrote:

    > Is there a perl version which prints 5 in case when,
    > perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'
    > I was almost sure that shift() should not break the aliasing.


    perl -le "sub f { $_=5 for shift } f(my $b=1); print $b"

    should do.

    --
    Bart
     
    Bart Van der Donck, Sep 22, 2005
    #2
    1. Advertising

  3. Matija Papec

    Paul Lalli Guest

    Matija Papec wrote:
    > Is there a perl version which prints 5 in case when,
    > perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'


    I can't imagine why such a thing would happen.

    > I was almost sure that shift() should not break the aliasing.


    shift() isn't breaking any aliasing. @_ is aliased to the arguments of
    f().
    `my $a = shift;` says to remove the first element of @_ and return a
    copy of it. This is no different than if you had said
    my $a = $_[0];
    $_[0] is an alias to the first argument of f(). $a is not. The only
    difference between this and your statement is that your statement also
    has the effect of removing the first element of @_.

    If you want to change the argument to f(), change it directly:
    $_[0] = 5;

    Paul Lalli
     
    Paul Lalli, Sep 22, 2005
    #3
  4. Matija Papec

    Guest

    Matija Papec <> wrote:
    > Is there a perl version which prints 5 in case when,
    > perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'
    >
    > I was almost sure that shift() should not break the aliasing.


    It is the assignment, not the shift, which is breaking the aliasing.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Sep 22, 2005
    #4
  5. Matija Papec

    Matija Papec Guest

    X-Ftn-To: Bart Van der Donck

    "Bart Van der Donck" <> wrote:
    >> perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'
    >> I was almost sure that shift() should not break the aliasing.

    >
    >perl -le "sub f { $_=5 for shift } f(my $b=1); print $b"
    >
    >should do.


    interesting, tnx!


    --
    Matija
     
    Matija Papec, Sep 22, 2005
    #5
  6. Matija Papec

    Matija Papec Guest

    X-Ftn-To: Paul Lalli

    "Paul Lalli" <> wrote:
    >> I was almost sure that shift() should not break the aliasing.

    >
    >shift() isn't breaking any aliasing. @_ is aliased to the arguments of
    >f().
    >`my $a = shift;` says to remove the first element of @_ and return a
    >copy of it. This is no different than if you had said
    >my $a = $_[0];
    >$_[0] is an alias to the first argument of f(). $a is not. The only
    >difference between this and your statement is that your statement also
    >has the effect of removing the first element of @_.
    >
    >If you want to change the argument to f(), change it directly:
    >$_[0] = 5;


    Yes, no doubt about that, but I think that I've read somewhere how shift
    keeps the "magic" when operating on @_.

    btw, Bart showed something interesting,
    perl -le "sub f { $_=5 for shift } f(my $b=1); print $b"

    should be doing the same thing as,
    perl -le "sub f { $_=5 for map $_, shift } f(my $b=1); print $b"

    but it doesn't?


    --
    Matija
     
    Matija Papec, Sep 22, 2005
    #6
  7. Matija Papec

    Paul Lalli Guest

    Matija Papec wrote:
    > X-Ftn-To: Paul Lalli
    >
    > "Paul Lalli" <> wrote:
    > >If you want to change the argument to f(), change it directly:
    > >$_[0] = 5;

    >
    > Yes, no doubt about that, but I think that I've read somewhere how shift
    > keeps the "magic" when operating on @_.


    Well, since your expected results clearly do not mesh with reality, it
    would seem that either 1) What you read was incorrect, or 2) You are
    misremembering or misunderstanding what you read. If you manage to
    find the citation you're talking about, please feel free to post it
    here for our examination...

    > btw, Bart showed something interesting,
    > perl -le "sub f { $_=5 for shift } f(my $b=1); print $b"
    >
    > should be doing the same thing as,
    > perl -le "sub f { $_=5 for map $_, shift } f(my $b=1); print $b"
    >
    > but it doesn't?


    I don't understand why you're assuming they *should* do the same thing.
    Let's stop using shortcuts and spell each of these out:
    sub f {
    foreach (shift @_){
    $_ = 5;
    }
    }
    In this one, $_ is an alias to each element of the list that foreach
    iterates over. @_ contains a list of aliases to f()'s arguments.
    shift() remove and returns the first element of @_. So the list that
    foreach iterates over is the first element of @_. Therefore, $_ is an
    alias to an alias to the first argument of f().

    sub f {
    foreach (map { $_ } shift @_) {
    $_ = 5;
    }
    }

    In this one, foreach is not iterating over the first element of @_.
    Instead, you're using map() to generate a new list, which will be
    composed of the values passed to it. Within the map block itself, $_
    is an alias to the first element of @_. The list that map returns
    however, is not an alias. It is this list that foreach is iterating
    over.

    Paul Lalli
     
    Paul Lalli, Sep 22, 2005
    #7
  8. Matija Papec

    Matija Papec Guest

    On 22 Sep 2005 13:26:23 -0700, "Paul Lalli" <> wrote:

    >I don't understand why you're assuming they *should* do the same thing.
    > Let's stop using shortcuts and spell each of these out:
    >sub f {
    > foreach (shift @_){
    > $_ = 5;
    > }
    >}
    >In this one, $_ is an alias to each element of the list that foreach
    >iterates over.


    ok.

    >@_ contains a list of aliases to f()'s arguments.
    >shift() remove and returns the first element of @_.

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ok.

    >So the list that
    >foreach iterates over is the first element of @_.


    How so? Doesn't foreach iterate over already shifted value which was
    previously _removed_ from @_?
    IMO, if it's removed from @_, it doesn't belong to @_ anymore..? :)

    >sub f {
    > foreach (map { $_ } shift @_) {
    > $_ = 5;
    > }
    >}
    >
    >In this one, foreach is not iterating over the first element of @_.


    Yes, it does not iterate over @_; I wrote it as the more obvious
    example of non @_ aliasing.
     
    Matija Papec, Sep 23, 2005
    #8
  9. Matija Papec

    Matija Papec Guest

    On Thu, 22 Sep 2005 19:24:08 GMT, Tim Hammerquist <>
    wrote:

    >> > Yes, no doubt about that, but I think that I've read
    >> > somewhere how shift keeps the "magic" when operating on @_.

    >>
    >> You probably read that, in order to avoid confusing,
    >> hard-to-find errors involving inadvertently changing aliased
    >> arguments, you should probably be making explicit copies of them
    >> by assigning them to lexically scoped vars unless you're sure
    >> you want to change the aliased variables.

    >
    >Or possibly the magic of shift() you mean is that, at package
    >scope, it operates on @ARGV by default, but inside a sub, it
    >defaults to @_.


    It could be, but that was a few years ago and my memory isn't doing me
    the justice.
     
    Matija Papec, Sep 23, 2005
    #9
  10. Paul Lalli wrote:

    > Matija Papec wrote:
    >
    >>Is there a perl version which prints 5 in case when,
    >>perl -le 'sub f {my $a = shift; $a=5} f(my $b=1); print $b'
    >>I was almost sure that shift() should not break the aliasing.

    >
    > shift() isn't breaking any aliasing.


    > If you want to change the argument to f(), change it directly:
    > $_[0] = 5;


    Or

    my $a = \shift; # or \$_[0]
    $$a = 5;

    Or see the Lexical::Alias module.
     
    Brian McCauley, Sep 23, 2005
    #10
  11. Matija Papec <> writes:

    > On 22 Sep 2005 13:26:23 -0700, "Paul Lalli" <> wrote:
    >
    >>I don't understand why you're assuming they *should* do the same thing.
    >> Let's stop using shortcuts and spell each of these out:
    >>sub f {
    >> foreach (shift @_){
    >> $_ = 5;
    >> }
    >>}
    >>In this one, $_ is an alias to each element of the list that foreach
    >>iterates over.

    >
    > ok.
    >
    >>@_ contains a list of aliases to f()'s arguments.
    >>shift() remove and returns the first element of @_.

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > ok.
    >
    >>So the list that
    >>foreach iterates over is the first element of @_.

    >
    > How so? Doesn't foreach iterate over already shifted value which was
    > previously _removed_ from @_?


    Yes. Think of it this way: @_ an array of aliases. You can change @_
    all you want, but its contents are still aliases. If you remove an
    alias from @_, then you can still assign to it, and change the
    original variable.

    The tricky bit comes when you do

    my $var = shift;

    That assigns a *copy* of the first element of @_ to $var. So the
    thing you assigned to $var is an alias, but $var is not.

    > IMO, if it's removed from @_, it doesn't belong to @_ anymore..? :)


    But it did when the sub was called, and that's what matters.

    -=Eric
     
    Eric Schwartz, Sep 23, 2005
    #11
  12. Matija Papec

    Matija Papec Guest

    X-Ftn-To: Eric Schwartz

    Eric Schwartz <> wrote:
    >> How so? Doesn't foreach iterate over already shifted value which was
    >> previously _removed_ from @_?

    >
    >Yes. Think of it this way: @_ an array of aliases. You can change @_
    >all you want, but its contents are still aliases. If you remove an
    >alias from @_, then you can still assign to it, and change the
    >original variable.
    >
    >The tricky bit comes when you do
    >
    >my $var = shift;
    >
    >That assigns a *copy* of the first element of @_ to $var. So the
    >thing you assigned to $var is an alias, but $var is not.


    Thanks, that makes sense. So the assignment actually breaks the "magic" as
    Xho already pointed out.


    --
    Matija
     
    Matija Papec, Sep 25, 2005
    #12
    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. Tim Tyler

    LCD anti-aliasing in Java

    Tim Tyler, Sep 4, 2003, in forum: Java
    Replies:
    2
    Views:
    1,291
    Tim Tyler
    Sep 5, 2003
  2. Kevin Bertman

    Anti-aliasing GIF Images

    Kevin Bertman, Nov 26, 2004, in forum: Java
    Replies:
    4
    Views:
    760
    marcus
    Nov 29, 2004
  3. Wesley T Perkins

    Aliasing a class name?

    Wesley T Perkins, Jun 28, 2005, in forum: Java
    Replies:
    8
    Views:
    1,979
    John Currier
    Jul 1, 2005
  4. Roedy Green

    More anti-aliasing puzzles

    Roedy Green, Aug 10, 2005, in forum: Java
    Replies:
    25
    Views:
    2,199
    Roedy Green
    Aug 16, 2005
  5. palmis

    aliasing

    palmis, Feb 2, 2006, in forum: Java
    Replies:
    0
    Views:
    736
    palmis
    Feb 2, 2006
Loading...

Share This Page