Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Operator Associative in Perl

by irah (Pilgrim)
on Jun 03, 2009 at 10:55 UTC ( [id://767967]=perlquestion: print w/replies, xml ) Need Help??

irah has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

When I run the following snippet, I got the output as,56555.

#!/usr/bin/perl use strict; use warnings; $a=5; printf("%d%d%d%d%d\n",$a++,$a--,++$a,--$a,$a);

In "perlop" man page, I read, there is no associative for '++' and '--' operator. I confused how this program working or executing?. When I run the same program in C, I got, 45555. Please explain how it is working?

Also I have a doubt "If the operator don't have any associative, how Perl will do that operation?."

Is there any side effect If I use same kind of operations?

Replies are listed 'Best First'.
Re: Operator Associative in Perl
by ikegami (Patriarch) on Jun 03, 2009 at 15:37 UTC

    there is no associative for '++' and '--' operator

    There are two major mistakes there.

    • You're actually concerned about the order in which the operands of the list operator (,) are evaluated.

    • Operand evaluation order has nothing to do with operator associativity (which determines precedence of instances of operators with the same precedence).

    While Perl doesn't document its operand evaluation order, it always evaluates operands from left to right for left-associative operators and exponentiation (**), and from right to left for assignments operators.

    This case is no exception. There are two characteristics (features?) of Perl that cause the result you observe:

    • Perl passes arguments to functions and subs by reference.

    • $a, --$a and ++$a return $a as an l-value.

    So, that means

    printf("%d%d%d%d%d\n",$a++,$a--,++$a,--$a,$a);
    is basically equivalent to
    do { local @_; alias $_[0] = "%d%d%d%d%d\n"; alias $_[1] = $a++; # Returns new value 5, $a=6 alias $_[2] = $a--; # Returns new value 6, $a=5 alias $_[3] = ++$a; # Returns $a (lvalue) $a=6 alias $_[4] = --$a; # Returns $a (lvalue) $a=5 alias $_[5] = $a; # Returns $a (lvalue) $a=5 \&printf; }
    When printf gets the values from @_, it sees
    • 5
    • 6
    • 5 (the current value of $a)
    • 5 (the current value of $a)
    • 5 (the current value of $a)

    When I run the same program in C, I got, 45555. Please explain how it is working?

    C leaves the operand evaluation order up to the compiler. Results will vary from compiler to compiler. It looks like yours passed by reference, evaluating from right to left.

      I find the difference between $a++ and ++$a as subroutine arguments to be quite interesting/surprising.

      In a subroutine the elements of @_ are usually aliases to the arguments of the subroutine call, allowing the subroutine to modify the caller's variables.

      In the case of ++$a, the corresponding element of @_ is a reference to the same IV as $a but in the case of $a++ it is a reference to a new IV, effectively preventing the subroutine from modifying the caller's variable. In both cases the array element is an lvalue (i.e. it can be modified), but only in the case of pre-increment can the subroutine modify the caller's variable.

      Using pre/post increment/decrement on an argument to a subroutine that attempts to modify that argument is not a good thing to do because the order of execution is not defined. None the less, the difference in implementation is interesting.

Re: Operator Associative in Perl
by lakshmananindia (Chaplain) on Jun 03, 2009 at 11:02 UTC

    From man perlop

    Note that just as in C, Perl doesn't define when the variable is incremented or decremented. You just know it will be done sometime before or after the value is returned. This also means that modifying a variable twice in the same statement will lead to undefined behaviour. Avoid statements like:

    $i = $i ++; print ++ $i + $i ++;

    Perl will not guarantee what the result of the above statements is.

    --Lakshmanan G.

    The great pleasure in my life is doing what people say you cannot do.


      Perl doesn't define when the variable is incremented or decremented. [...] Perl will not guarantee what the result of the above statements is.

      While operand evaluation order isn't documented, the order is the same in all versions on all platforms (intentionally), and changing it would break a lot of code.

      perl always evaluates operands from left to right for left-associative operators and exponentiation (**), and from right to left for assignments operators.

Re: Operator Associative in Perl
by JavaFan (Canon) on Jun 03, 2009 at 12:59 UTC
    Basically what you are saying is, "give me the value of $a, increment it sometimes afterwards", "give me the value of $a, decrement it sometimes afterwards", "give me the value of $a but only after you've incremented it", "give me the value of $a, but only after you've decremented it". Note that you never say at which moment the value of $a needs to change, just that it needs changing sometime before (or after) fetching the value.

    Getting 56555 is not unreasonable. But another result wouldn't have been unreasonable either. In general, it's a bad idea to use ++ or -- twice on the same variable in the same statement is a bad idea. Or to assign to a variable in the same statement as you apply ++ or -- to that variable.

      JavaFan said:
      >In general, it's a bad idea to use ++ or -- twice on the >same variable in the same statement is a bad idea.

      The paralell of the repitition in the sentence to the original topic gave me quite a chuckle. I hope it was intentional.

        It wasn't intentional, but it does stress it's a bad idea. ;-)
Re: Operator Associative in Perl
by nagalenoj (Friar) on Jun 03, 2009 at 13:33 UTC

    I remember brainbench questions on seeing your question. It's really interesting when solving the problems like this.

      When I run the same program in C, I got, 45555

    Like this, many things differs across languages. No need to compare with other languages.

    As Javafan said, its good not to use these kind of code and its better not to confuse your team and maintainers.

      ... its good not to use these kind of code and its better not to confuse your team and maintainers.
      When I was a kid, we often went to Saturday afternoon horror or monster movie matinees. Sometimes they would show a 3-D movie that used anaglyphic viewers, cheap cardboard 'glasses' with a red or green filter over each eye. The viewers were always clearly marked as to which color filter went with which eye, right or left. Some kids always insisted on wearing the viewers backwards. They always got headaches. Something similar is happening here.

      And while we're (more or less) on the topic of 50's sci-fi, and with reference to the example expression of the OP...

      "Man does not look upon the face of the Gorgon and live."
      Morbius, Forbidden Planet, 1956

      Update: In Morbius quote: made slight correction, added reference to pertinent topic.

Re: Operator Associative in Perl
by vinoth.ree (Monsignor) on Jun 03, 2009 at 11:00 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://767967]
Approved by vinoth.ree
Front-paged by vinoth.ree
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-04-25 06:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found