Simple question(s) about Mojo::Collection map and Mojo::DOM attr

94 views
Skip to first unread message

ddal...@gmail.com

unread,
Mar 20, 2016, 3:37:16 PM3/20/16
to Mojolicious
I'm brand new to Mojolicious (less than a week) and have some hopefully simple questions about the Mojo::Collection map and Mojo::DOM attr methods (Mojolicious v6.53).

I've seen numerous code examples similar to the following which don't *seem* to match the map method signature in the documentation.

my $product_ids = $dom->find('div[id*="item-"][class="product"][data-in-stock="yes"]')->map(attr=>'id');

my $item_price = $dom->find('h3[itemprop="price"]')->map('text');


Both of these map method calls work (produce the intended result) but I'm scratching my head how / why they work given the documentation on the Mojo::Collection map method (and the source too).   The first example sure looks like a hash element being passed and the second example, a string, neither of which appear to be a callback or method reference shown in the documentation.  Curiously, these map method calls look like the method signatures for the Mojo::DOM attr method.   

Instead of the map calls in the above, could / should I be using attr method calls?   But the result of a $dom->find() call is a Mojo::Collection object... and attr is a Mojo::DOM method.

Clearly, I'm missing something fundamental here.  Help?


And one more newbie question, is there a good reason (e.g., backward compatibility with earlier releases) to use the Mojo::Collection to_array method to access an element of a Mojo::Collection?  

my $item_price = $dom->find('h3[itemprop="price"]')->map('text')->to_array->[0];

versus

my $item_price = $dom->find('h3[itemprop="price"]')->map('text')->[0];


Thank you.

... Dewey

sri

unread,
Mar 20, 2016, 8:11:48 PM3/20/16
to Mojolicious
The first example sure looks like a hash element being passed and the second example, a string, neither of which appear to be a callback or method reference shown in the documentation.

I've updated the example, it should be a little more obvious now.

 
And one more newbie question, is there a good reason (e.g., backward compatibility with earlier releases) to use the Mojo::Collection to_array method to access an element of a Mojo::Collection?

The to_array method is actually less backwards compatible, and exists for stuff like "$c->render(json => $collection->to_array);". ;)

--
sebastian

ddal...@gmail.com

unread,
Mar 20, 2016, 8:46:02 PM3/20/16
to Mojolicious
To try to answer my own questions....

Assuming the find returns a single element, the following lines are equivalent.  This seems to show that the Mojo::Collection method call map('text') calls the Mojo::DOM text method for each element in the collection -- returning a list (Collection) of the text values of the elements.

my $item_price = $dom->find('h3[itemprop="price"]')->map('text')->[0];

my $item_price = $dom->find('h3[itemprop="price"]')->[0]->text;

And the following lines are equivalent (sort of).  Both return the id attribute value for the first element returned by the find method call.  The second line would seem to be more efficient when multiple elements are returned by the find call.  This seems to show that map(attr=>"id") calls the Mojo::DOM attr method (with a parameter value of 'id') for each element in the collection.

my $item_id1 = $dom->find('div[id*="item-"][class="product"][data-in-stock="yes"]')->map(attr=>'id')->[0];

my $item_id1 = $dom->find('div[id*="item-"][class="product"][data-in-stock="yes"]')->[0]->attr('id');

Maybe?
Reply all
Reply to author
Forward
0 new messages