Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Conditional array initialisation?

by BrowserUk (Pope)
on Jul 12, 2013 at 16:59 UTC ( #1044027=perlquestion: print w/ replies, xml ) Need Help??
BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

Why don't these work?

@a //= ( 1..3 );; [Can't modify array dereference in defined or assignment (//=) at (eva +l 9) line 1, at EOF ( @a ) //= ( 1..3 );; [Can't modify array dereference in defined or assignment (//=) at (eva +l 10) line 1, at EOF ( @a ) ||= ( 1..3 );; [Can't modify array dereference in logical or assignment (||=) at (eva +l 11) line 1, at EOF

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Comment on Conditional array initialisation?
Download Code
Re: Conditinal array initialisation?
by hdb (Parson) on Jul 12, 2013 at 17:18 UTC

    From defined:

    Use of defined on aggregates (hashes and arrays) is deprecated. It used to report whether memory for that aggregate had ever been allocated. This behavior may disappear in future versions of Perl.
      The explanation is even more confusing than the question.

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      My blog: Imperial Deltronics

      That it doesn't work is clear.

      But, the semantics seem very clear, and the implementation trivial (roughly, without the need for copying):

      undef @a; @a = @a ? @a : (1..3); say @a;; 1 2 3 @a = (4..6); @a = @a ? @a : (1..3); say @a;; 4 5 6

      So I wondered why it isn't implemented so?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Conditional array initialisation?
by Kordaff (Acolyte) on Jul 12, 2013 at 19:22 UTC
    From perldoc perlop: Logical Defined-Or Although it has no direct equivalent in C, Perl's // operator is related to its C-style or. In fact, it's exactly the same as ||, except that it tests the left hand side's definedness instead of its truth. Thus, EXPR1 // EXPR2 returns the value of EXPR1 if it's defined, otherwise, the value of EXPR2 is returned. (EXPR1 is evaluated in scalar context, EXPR2 in the context of // itself). Usually, this is the same result as defined(EXPR1) ? EXPR1 : EXPR2 (except that the ternary-operator form can be used as a lvalue, while EXPR1 // EXPR2 cannot). This is very useful for providing default values for variables. If you actually want to test if at least one of $a and $b is defined, use defined($a // $b) .

      I'm not sure how you think any of that is relevant.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Conditional array initialisation?
by LanX (Canon) on Jul 12, 2013 at 19:38 UTC
    I suppose you want to assign default values to empty arrays only ("doesn't work" ???)

    Using defined doesn't make sense here (see also hdb's reply), and the other expression has to be analogous to

    DB<125> @a=() DB<126> @a = (@a || ( 1..3 )); => (1, 2, 3) DB<127> @a = (@a || ( 4..6 )); => 3

    But the second case fails cause the LHS of an or operator is evaluated in scalar context.

    We had a longer discussion about this some weeks ago, which I didn't really follow (maybe somenone can link to it)

    FWIW this works:

    DB<138> @a=() DB<139> @a = (4..6) if !@a => (4, 5, 6) DB<140> @a=() DB<141> @a = @a ? @a : ( 1..6 ) ; => (1, 2, 3, 4, 5, 6) DB<142> @a = @a ? @a : ( 42 ) ; => (1, 2, 3, 4, 5, 6) DB<143> @a = (4..6) if !@a => "" DB<144> \@a => [1, 2, 3, 4, 5, 6]

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      Using defined doesn't make sense here

      Why not?

      @used = 1; say defined @used ? '1' : '0'; 1 say defined @neverUsed ? '1' : '0';; 0

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
      /div
        The old use of defined @arr is deprecated, cause the logic was broken.

        For me undefined means "not initialized" (yet), like with  my $a. But this state doesn't exist for array and hashes, they are initialized empty.

        And if it existed it would be different from (defined and) empty.

        Nevertheless undef @a is allowed, adding even more confusion:

        DB<153> @a => (1, 2, 3, 4, 5, 6) DB<154> undef @a => undef DB<155> \@a => []

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: Conditional array initialisation?
by abualiga (Scribe) on Jul 13, 2013 at 01:01 UTC
    I just started reading the Perl Cookbook, and came across a similar example (chapter1 Strings, p12), only with ||= as //= was not implemented at the time of publication. It says don't extend the use of the ||= assignment operator to arrays and hashes, because the operators put the left operand into scalar context. Instead use the ternary operator, like you did later.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2014-08-22 04:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (146 votes), past polls