Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^7: Using 'keys' on a list (update x2)

by The Perlman (Scribe)
on Jun 30, 2021 at 16:14 UTC ( [id://11134506]=note: print w/replies, xml ) Need Help??


in reply to Re^6: Using 'keys' on a list (update x2)
in thread Using 'keys' on a list

From the OP:

"Suppose a function f() returns an even-sized list..."

- Ron
  • Comment on Re^7: Using 'keys' on a list (update x2)

Replies are listed 'Best First'.
Re^8: Using 'keys' on a list (update x2)
by Anonymous Monk on Jun 30, 2021 at 17:17 UTC
    From the OP: "Suppose a function f() returns an even-sized list..."

    so what? sub f { %hash } scalar(f) is the same as scalar(%hash)

      modified: my fault, I do this on one line, and I rewrote code when I post them, I trust they are same.
      apparently, they are not.

      and I find I should just quote this:"Called in list context, ...", from perldoc...

      Only focus on op's condition...

      use strict; use warnings; use feature 'say'; sub f {a => 1, b=>2} my $foo = f(); my $bar = join '_', f(); say $foo; say $bar; #outputs 2 a_1_b_2

      so that's why I assume the first argument keys accept is 'a', like join.
      I just want to explain keys don't work for that single scalar value.

      but but... keys looks like do not accept arguments in scalar context
      if we write:

      sub f {a => 1, b=>2} my @all_key = keys f();
      the warning message is "Type of arg 1 to keys must be hash or array (not subroutine entry)"
      so I tried it:
      sub f {a => 1, b=>2} my %h = (c => 3); say keys %h, f(); #output: c
      and then if we write:
      sub f {a => 1, b=>2} my %h = (c => 3); say keys f(), %h; #warnings: Experimental keys on scalar is now forbidden at perl.pl line 11. Type of arg 1 to keys must be hash or array (not subroutine entry) at +perl.pl line 11, near ")," Execution of perl.pl aborted due to compilation errors.
      so, this is why I think it is 'a'.
      I guess the first argument of keys is the first element in list.
      p.s. I should come back earlier...


      edit: my fault, I type '}' as ')' ... thanks The Perlman and LanX, I had modified them:(
      yes, I find every result different now. I write them on one line... here I redo all:

      use strict; use warnings; use feature 'say'; sub f {a => 1, b=>2} my $foo = f(); my $bar = join '_', f(); say $foo; say $bar; #output 2 a_1_b_2 sub f {a => 1, b=>2} my @all_key = keys f(); #warnings: Experimental keys on scalar is now forbidden at call_art.pl line 7. Type of arg 1 to keys must be hash or array (not subroutine entry) at +call_art.pl line 7, near ");" Execution of call_art.pl aborted due to compilation errors. sub f {a => 1, b=>2} my %h = (c => 3); say keys %h, f(); #output ca1b2 sub f {a => 1, b=>2} my %h = (c => 3); say keys f(), %h; #warnings: Experimental keys on scalar is now forbidden at call_art.pl line 8. Type of arg 1 to keys must be hash or array (not subroutine entry) at +call_art.pl line 8, near ")," Execution of call_art.pl aborted due to compilation errors.

        all your code examples are broken (multiply) and don't compile.

        At the same time you claim the output is factual.

        Please don't do this!!!

        Point is that keys' prototype expects one %hash or @array not a scalar.

        And the argument must start with % or @

        DB<20> p prototype "CORE::keys" \[%@] DB<21> p keys @a DB<22> p keys %a DB<23> p keys $a Experimental keys on scalar is now forbidden at (eval 32)[c:/Strawberr +y/perl/lib/perl5db.pl:738] line 2. Type of arg 1 to keys must be hash or array (not scalar dereference) a +t (eval 32)[c:/Strawberry/perl/lib/perl5db.pl:\ 738] line 2, at EOF DB<24>

        The point you should make is that there has to be exactly ONE argument!

        That's why keys can't expect a LIST.

        and this can't be changed with a new feature, because otherwise old code would break.

        Consider

        @all_keys = keys %h1, keys %h2;

        which will parse like

        @all_keys = keys(%h1), keys(%h2);

        and collect the keys from %h1 and %h2

        DB<26> %h1=(a=>1) DB<27> %h2=(b=>2) DB<28> x @all_keys = keys %h1, keys %h2 0 'a' 1 'b' DB<29>

        Now, if keys LIST was allowed, than the first keys would try to consume the rest of the list.

        @all_keys = keys( %h1, keys(%h2) );

        That's why the idea of the OP can't be implemented, without breaking backwards compatibility!

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        >
        sub f {a => 1, b=>2} my %h = (c => 3); say keys %h, f(); #output: c

        This is definitely also wrong, say will print the list from f()

        D:\>perl -Mfeature=say sub f {a => 1, b=>2} my %h = (c => 3); say keys %h, f(); __END__ ca1b2 D:\>

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

         sub f {a => 1, b=>2) doesn't compile :)
        - Ron

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (8)
As of 2024-04-16 16:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found