Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

RE: RE: Re: Possible pitfall with Slices

by fundflow (Chaplain)
on Nov 07, 2000 at 01:29 UTC ( [id://40247]=note: print w/replies, xml ) Need Help??


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

Your posts give partial answer. While it is possible to use exist() in my example above, it is not always what you want. What if the actual value is important?
e.g.
@employess=( 'This guy', 'That guy', 'Fastofle'); @base_salary{@employees}= 100000; or @netmask{@mymachines}="255.255.0.0";

In any case, some people (like me) might fall in to this trap and the subject of my post was to warn them.

Replies are listed 'Best First'.
RE: RE: RE: Re: Possible pitfall with Slices
by arturo (Vicar) on Nov 07, 2000 at 01:33 UTC

    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} = "255.255.0.0" 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 "255.255.0.0" -- list context confuses me yet again! =) To get a list as long as @mymachines, you need to do

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

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

      Oh man...

      Why?

      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 "255.255.0.0" 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.

        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.
        vs.
        (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

RE: RE: RE: Re: Possible pitfall with Slices
by Fastolfe (Vicar) on Nov 07, 2000 at 01:36 UTC
    The code I posted was relevant only to the example you gave. Sorry if that wasn't clear. I did not intend to suggest that exists is the best thing to use in all circumstances. If the values of your hash are important, by all means inspect them. If you're just filling a hash to keep track of the presence of certain items (keys), however, it's a little cleaner to simply see if that key exists in the hash, not to try and test for a true value at $hash{$key}.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2024-03-28 18:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found