4

Let's say I have the following Groovy code:

String name = child.getParent()?.getParent()?.getName();

Note that getParent() may return null, and in this case the code continues to work without null pointer exceptions being thrown.

Is there a way to do this clearly in one line in Perl 5.8? I am open to writing a generic helper method to accomplish this.

I'm running into situations where I have several nested objects and am having to do something like:

my $name = $child && $child->getParent && $child->getParent->getParent && $child->getParent->getParent->getName;

Yes this is in one line, but is fugly IMO.

Borodin
  • 126,100
  • 9
  • 70
  • 144
lots_of_questions
  • 1,109
  • 3
  • 16
  • 24
  • 1
    Related: [How do I handle errors in methods chains in Perl?](http://stackoverflow.com/questions/7064975/how-do-i-handle-errors-in-methods-chains-in-perl) – ThisSuitIsBlackNot Apr 08 '15 at 17:27
  • This is where a query language (such as XPath or CSS selector) would be useful. – ikegami Apr 08 '15 at 17:34
  • It isn't clear whether you need to implement this Groovy code in Perl, or if you've just found another way to snipe at Perl. Are you being serious? – Borodin Apr 08 '15 at 17:45
  • @Borodin - Yes I am serious, my team owns a large existing code base in perl. – lots_of_questions Apr 08 '15 at 19:35
  • @lots_of_questions: Okay, so where does Groovy fit in? – Borodin Apr 08 '15 at 20:05
  • @Borodin, groovy fits in because I am aware it has this feature. I was simply wondering if there was an equivalent in perl which had the same level of compactness. – lots_of_questions Apr 08 '15 at 20:13
  • 2
    I'll point out - Perl 5.8 was released in 2003, and was end of life in 2008. It may be worth considering moving to a _slightly_ newer release. – Sobrique Apr 09 '15 at 09:15

3 Answers3

3

In my opinion, your original Groovy code is on the boundary of readability anyway. I would implement it rather differently, but a similar expression in Perl would be

my $name = (
    $node = $node->get_parent or
    $node = $node->get_parent or
    $node->get_name
);

The utility of a language isn't defined by its ability to represent complex constructs in very few characters

Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 1
    for the sake of readability: in groovy one would write `child.parent?.parent?.name` OPs code is verbose/javaish. – cfrick Apr 09 '15 at 10:02
0

probably a bit evil is using eval:

my $name = eval { $child->getParent->getParent->getName }

an alternative is to make use of last which can be used to leave a block (i.e. a standalone {...} is similar to for(1) {...}):

my $name; { $name = (($child->getParent || last)->getParent || last)->getName }
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
0

It looks like you want to extract information from the DOM of a HTML page. For this I recommend that you use a Perl module that just does that. Have a look at Mojo::DOM

BarneySchmale
  • 658
  • 1
  • 4
  • 10