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

I think the problem I'm seeing is related to context.

WWW::Mechanize clearly states:
$mech->links
Lists all the links on the current page. Each link is a WWW::Mechanize::Link object. In list context, returns a list of all links. In scalar context, returns an array reference of all links.

Ok, great.

@links = $mech->links; foreach (@links){ print $_->url(), "\n"; }

Fine, this prints out the URLs as I would expect it to. No problem.

http://www.xxx.com
http://www.yyy.com
http://www.zzz.com

@links = $mech->links; foreach (@links){ print "Would get --> $_->url()\n"; }
This however prints:

Would get --> WWW::Mechanize::Link=ARRAY(0x97bbfbc)->url()
Would get --> WWW::Mechanize::Link=ARRAY(0x97cba68)->url()
Would get --> WWW::Mechanize::Link=ARRAY(0x97cb978)->url()

What I do not understand is what is the difference? Thanks for any enlightenment,
Mike


Update: Thanks ikegami and sk for the very clear answers and explanations as well as the working alternatives. Very much appreciated.

2005-10-13 Retitled by g0n, as per Monastery guidelines
Original title: 'Context'

Replies are listed 'Best First'.
Re: Question about WWW::Mechanize::Link string interpolation
by ikegami (Patriarch) on Oct 13, 2005 at 05:41 UTC

    The difference is that one is in quotes and the other one isn't. Method calls don't get interpolated; just scalar and array variables get interpolated (including indexed arrays and array slices, with or without dereferences). In your example, $_ is getting interpolated, but the ->url() bit is treated as just plain text. (You can see it at the end of every line in the output.) Working alternatives:

    print "Would get --> ", $_->url(), "\n"; or print "Would get --> " . $_->url() . "\n"; or print "Would get --> @{[ $_->url() ]}\n";
Re: Question about WWW::Mechanize::Link string interpolation
by sk (Curate) on Oct 13, 2005 at 05:43 UTC
    Double quoted strings do not interpolate methods. It just interpolate scalars and arrays. So when Perl sees  "$scalar->something()" it evaluates $scalar first, that's why you get the reference instead of the URL. In your case ->url() is treated as literal string and prints it as is.

    A simple example -

    #!/usr/bin/perl use strict; use warnings; my $sub_ref = \&hi; print $sub_ref->(); print "$sub_ref->()", $/; sub hi { return "hi\n"; } __END__ hi CODE(0x8ad0834)->()