Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
laziness, impatience, and hubris
 
PerlMonks  

Re^2: Conditional array initialisation?

by BrowserUk (Pope)
on Jul 12, 2013 at 19:58 UTC ( #1044070=note: print w/ replies, xml ) Need Help??


in reply to Re: Conditional array initialisation?
in thread Conditional array initialisation?

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


Comment on Re^2: Conditional array initialisation?
Download Code
Re^3: Conditional array initialisation?
by LanX (Abbot) on Jul 12, 2013 at 20:19 UTC
    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)

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

      I don't see any confusion nor potential for it.

      If I have a scalar and at some point in my code I wish to check if it currently has a value, and if it does not, set it, I might write:

      my $x; ... $x = getValue() unless defined $x;

      More recently, I'd write that as: $x //= getValue();. Clear concise semantics.

      If have an array, and at some point in my code I want to check if it contains anything, and populate it if it does not, I might write:

      my @a; ... @a = getValues() unless @a;

      Thus using the value of the array in a scalar context to decide if the array is empty or not.

      It seems a natural, semantically clear, easily implemented extension of the scalar case above to write that as:

      @a //= getValues();

      Test the scalar context value of the array, and if it is false, assign the list on the right hand side to the array on the left.

      Indeed, it seemed so logically analogous, and semantically clear, that I wrote it and expected it to work, and I was taken by considerable surprise that it didn't.

      Hence my OP.


      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.
        If have an array, and at some point in my code I want to check if it contains anything,

        I'm not sure why you are throwing in "defined" in this scenario. Your scenario makes perfect sense for a Boolean test but, indeed, there was often confusion with "defined" related to your stated purpose:

        $ perl -del > x defined @a '' > @a = (1..3) > x defined @a 1 > @a = () > x defined @a 1

        That is, people were often asking "defined @a" when they meant "is @a empty". The mistake was so common (you appear to have just made that mistake yourself) that "defined @a" was made to complain.

        But that seems mostly a distraction from your original question, which should be restricted to ||= (since //= doesn't mean what you thought it did).

        So why doesn't @a ||= (1..3); work? Well, the definition of ||= implies that such should be the same as @a = @a || (1..3). But you never wrote that as an alternative... because it doesn't work, either.

        @a = @a || (1..3); doesn't "work" because the left side of || is in a scalar context so it is the same as @a = 0+@a || (1..3);. Which means it changes @a when @a isn't empty. (FYI, I'm sure BrowserUk knew this, so I'm just explaining that for other readers.)

        I'm certainly sympathetic to the argument that it makes sense to special-case @a ||= ... so that it will DWYM. I can see somebody arguing against it because they worry it will make it more likely for people to mistakenly write @a || .... Or because it breaks the rules about how ||= was defined.

        I find both sides of that argument roughly equally persuasive.

        My response as to why @a ||= ... doesn't work is simply that nobody has taken the time to special-case it to make it DWYM instead of making it match @a = @a || ...

        I'll suggest the following alternative idiom:

        @a or @a = (1..3);

        Maybe that will lead to somebody adding an or= operator so you can then write @a or= (1..3);?

        - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1044070]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (11)
As of 2014-04-23 23:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (556 votes), past polls