Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

RE: RE: RE: Re: Possible pitfall with Slices

by arturo (Vicar)
on Nov 07, 2000 at 01:33 UTC ( #40249=note: print w/replies, xml ) Need Help??

in reply to RE: RE: Re: Possible pitfall with Slices
in thread Possible pitfall with Slices

OK, it is a potential pitfall, but why would you expect a single value (or list of size 1) to get stretched automatically as big as the size of the list you're using in the hash slice? Better to do something like:

@netmask{@mymachines} = "" x scalar @mymachines;

Which makes your intent as obvious as it could be.

Update Fastolfe reminds me that the above code won't do what I want it to. (it would generate a scalar that consists of the size of @mymachines iterations of "" -- list context confuses me yet again! =) To get a list as long as @mymachines, you need to do

@netmask{@mymachines} = ("") x scalar @mymachines;

Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Replies are listed 'Best First'.
RE: RE: RE: RE: Re: Possible pitfall with Slices
by fundflow (Chaplain) on Nov 07, 2000 at 01:41 UTC
    Oh man...


    Possible answers:

    1. Because it makes sense
    2. Because other languages have it
    3. Because people might want it
    4. Because it could make programs cleaner
    5. Because it could be faster (no need to generate an array)
    6. Because the current way generates a silent bug
    7. Why not?

    Also: Do you know what "" x scalar @mymachines; returns?
    (hint: not a list)

      I'd actually consider it inconsistent behavior. Consider the following, which strongly resembles code I've read today:
      sub genWhereString { my ($fields, $where, $orderby) = @_; my $query = "select " . join(", ", @$fields); $query .= " " . join(" and ", @$where) if $where; $query .= $orderby if $orderby; my $sth = $dbh->prepare($query) || return $DBI::errstr; # et cetera
      Obviously, the intent is that $where and $orderby CAN be undefined. If your change went through, would $where and $orderby become copies of $fields if they were undefined?

      "Ah!" you say, "Simply change things so that a single-element, evaluated in list context, becomes an infinitely-long list of that element repeated."

      Once you realize why that's not so good, you'll realize why the existing behavior makes sense. Yeah, this context stuff is hard to grasp at first. Once it sinks in, though, you'll wonder how other languages get by without it.

      The idea of generating a special case for hash slices is a supremely bad idea. If you know enough to understand why @foo{@list} is still a hash even though it doesn't have the happy % in front of it, you're not too far from understanding that a scalar in list context might as well be a single element list.

      Update: A one-element list has the same listishness as a ten-element list. It does not have as many values as the ten element list. That is the essential difference. In assignment #2 below, the scalar is evaluated in list context, which confers listishness upon it. However, the number of values it contains is only one.

      In other words, when the interpreter encounters this behavior (assigning a shorter list of values to a longer list), how would your method handle the following cases?

      1. my @a = (1 .. 10); my @b = (1 .. 3); @a = @b;
        Obviously the correct behavior is that @a will contain three elements. If @b were somehow extended, would @a then be expected to contain qw ( 1 2 3 1 2 3 1 2 3 1 ) or qw( 1 2 3 3 3 3 3 3 3 3 )?
      2. my @a = (1 .. 10); @a = (1 .. 5);
        Again, the correct behavior is that @a will contain five values.
      3. my @a = (1 .. 10); @a = 1;
        Here is the clearest place where your technique should come into play. Would @a thus contain qw ( 1 1 1 1 1 1 1 1 1 1 )?
      4. my @a = (1 .. 10); @a = some_sub_returning_one_or_more_results();
        Suppose that subroutine performs a set operation, such as a union or intersection. There's no way of knowing, at compile time, how many results it will return. Suppose that for certain parameters, it returns one value. Should that be repeated to fill the available slots?
    List assignment is list assignment. In my opinion, changing the fundamental behavior of Perl (and the difference between list and scalar context puts the fun in fundamental) because you don't yet understand it is a bad idea.
        In your example, @_ is a list.

        Syntacticaly, it seems like the following assignments are easy to distinguish:
        1. list=list
        2. list=scalar

        I can see reasons why not, maybe a 'scalar' is automatically promoted to a '1-element list'.

        If this is not the case, then my suggestion was that in case (2), which doesn't seem to make sense anyway, either a warning will be given or the whole slice be set to the given value.
        Case (1) is the same ol' perl.

      But it *doesn't* make sense, at least not automatically. First, I don't see how it makes programs any cleaner. How is the interpreter to know when you want

      (a) to assign as many values as you have to the keys of the hash, leaving the 'extra' keys associated with undef.
      (b) to assign each one the same?

      All I'm saying is that the version I posted is unambiguous (maintainability). As for speed, well, isn't the interpreter going to have to essentially create the array?

      Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://40249]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2018-05-21 23:27 GMT
Find Nodes?
    Voting Booth?