Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Popping from method that returns a list in one line

by nysus (Parson)
on Aug 28, 2019 at 23:10 UTC ( [id://11105192]=perlquestion: print w/replies, xml ) Need Help??

nysus has asked for the wisdom of the Perl Monks concerning the following question:

I have the following:

pop ($fp->get_files));

which gives "Experimental pop on scalar is now forbidden, near "->get_files)"" error. But

pop @{$fp->get_files}

Doesn't work either and gives an error: "Can't use string ("25") as an ARRAY ref while "strict refs" in use".

$f->get_files returns a list. I've tried other contortions but without success. Is there a way to do this in one line?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Popping from method that returns a list in one line
by jcb (Parson) on Aug 28, 2019 at 23:44 UTC

    You cannot pop the return value of ->get_files because it is not an array.

    pop @{[$fp->get_files]}

    That should work, but should make the uselessness of this obvious: it constructs an array from the list returned by ->get_files, removes the last value from that array, and then throws the entire array away.

    If this is part of File::Collector, I do not see a way for ->get_files to do what you seem to want, although you could add a ->get_file_queue method that returns a reference to the current file queue for a category. If I understand correctly, this would be return $s->{"_iterator_$type"} (but you should probably change your instance variables to make that return $s->{iterators}{$type} instead).

      You cannot pop the return value of ->get_files because it is not an array.

      For an explanation of why this makes a difference, see the FAQ:

      perldoc -q "What is the difference between a list and an array"

      The Synopsis section of the documentation pop specifies that it requires an array.

      Bill

      Thanks. I was just writing a quick and dirty test for the module and ran across this issue.

      ok $fp->get_data(pop @{($fp->get_parseable_files)}), 'can get data from file';

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        which prolly should be

        ok $fp->get_data(pop @{[$fp->get_parseable_files]}), 'can get data fro +m file';
        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

        Or maybe (untested):
            ok $fp->get_data(($fp->get_parseable_files)[-1]), 'can get data from file';


        Give a man a fish:  <%-{-{-{-<

Re: Popping from method that returns a list in one line
by haukex (Archbishop) on Aug 29, 2019 at 07:08 UTC
    $f->get_files returns a list.

    To get into the details of what's going on: There is a difference between return ("foo","bar") (list) and return @quz (array) in scalar context. The context of the call is basically passed through to the return, so it's like $x = ("foo","bar"), where the comma operator in scalar context throws away the item on the left and returns the item on the right, and $x = @quz gets the number of elements in the array. So I suspect your method is probably returning an array instead of a list. That's also why neither of the forms you showed work, as @{...} provides scalar context, and you're getting the error because you can only give an actual array directly to pop (it currently has a prototype of (;\@), which means it accepts only things that start with an @). Two approaches might be ($fp->get_files)[-1], as others have already mentioned, or to actually return an array reference from the method, and dereference that with @{...}, but that'll change your API.

Re: Popping from method that returns a list in one line
by 1nickt (Canon) on Aug 28, 2019 at 23:30 UTC

    Hi, as you can see, it's usually best to return references to arrays and hashes from functions.

    But what about

    ($fp->get_files)[-1]
    ?

    Hope this helps!


    The way forward always starts with a minimal test.

      E.g.:

      c:\@Work\Perl\monks>perl -wMstrict -le "sub foo { return qw(foo bar baz quux); } ;; my $o = bless \do {my $x}; ;; my $like_as_if_it_was_popped = ($o->foo)[-1]; print $like_as_if_it_was_popped; " quux


      Give a man a fish:  <%-{-{-{-<

Re: Popping from method that returns a list in one line
by shmem (Chancellor) on Aug 28, 2019 at 23:52 UTC

    perl v5.20.2:

    use strict; use warnings; # yadda yadda use 5.10.0; sub foo { my $ary = [1..10]; $ary } my $o = bless \do {my $x}; say "this: ", pop @{$o->foo}; __END__ this: 10

    also:

    use strict; use warnings; # yadda yadda use 5.10.0; sub foo { (1..10) } my $o = bless \do {my $x}; say "this: ", pop @{[$o->foo]}; __END__ this: 10
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-03-28 13:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found