in reply to Re: Re: Re: Autoboxing: Yes or No?
in thread Autoboxing: Yes or No?

I think this is a problem best left unaddressed. In general OO the Law of Demeter forbids such deep hierarchy navigation constructs.

Now, manipulating XML (or other document) structures is a very specific case, and not all the common OO rules necessarily apply. However, I'd argue that this means you should rather be using a language addressed at this specific problem domain. Which in this case does exist and should be obvious: XPath. Indeed, something like this behaves exactly the way you specified:

# LibXML lingo; XPath expr is off the cuff, untested $doc->findvalue('/section[last()]/title[1]/@num');

All that said, even methods on undef would not really solve the issue, just sweep it under the rug. Doing this well and cleanly in Perl would require something along the lines of

$doc->root(sub { $_->last_child( 'section', sub { $_->first_child( 'title', sub { $_->att( 'num') }) }) });

In summary, you will not be able to solve this satisfactorily and concisely in a language without continuations. Which isn't so bad, because this particular problem is likely better left unsolved.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^4: Autoboxing: Yes or No?
by Ovid (Cardinal) on Jan 02, 2004 at 00:24 UTC

    Aristotle wrote: I think this is a problem best left unaddressed. In general OO the Law of Demeter forbids such deep hierarchy navigation constructs.

    I am wondering if I missed what you were trying to say. The Law of Demeter lets us know that this is bad:

    my $company = $sales_rep ->office ->division ->company;

    This enforces a class heirarchy which becomes inflexible since the user's code must now know the class heirarchy (bad!) and this makes changing the heirarchy more difficult. However, there's nothing wrong with this:

    $sales_rep ->set_title($title) ->set_office($office) ->set_something_else($foo);

    In this case, there is no enforcement of a particular class heirarchy and you therefore aren't bound by one. With mirod's example, I think we have the same thing:

    $doc ->root ->last_child('section') ->first_child('title') ->att('num')'

    While these are accessors and not mutators, we still appear to only be dealing with only one class and are less concerned with restructuring things. We have a published interface that only one class needs to maintain, whereas with my first example, we appear to have the various classes needing to know about the published interfaces of other classes and this greatly compounds the problem, thus increasing maintenance costs.

    If I am misunderstanding the situation (or your objection), please let me know.

    Cheers,
    Ovid

    New address of my CGI Course.

      Yes, this is indeed no violation of Demeter's Law. I was arguing that navigating node hierarchies is better left to a language tailored to the problem domain. So we have three conceivable cases where such method call chains appear: one is a design problem, one is better addressed on a different level, and the other (ie returning $self from a mutator - which is really a Perl-only idiom) is not really an issue WRT this discussion.

      Makeshifts last the longest.

Re^5: Autoboxing: Yes or No?
by mirod (Canon) on Jan 02, 2004 at 01:57 UTC

    I agree with using XPath... if it's available. It is now available for XML::Twig but that's quite recent. Also in this case I used only accessors, but as pointed by ovid, I could have used setters or other methods.

    And yes, it mostly "sweeps the issue under the rug", the same way Perl itself sweeps under the rug the fact that $ sometimes matches just the end of the string, and sometimes matches a line return and the end of the string. It might not always be the correct thing to do, it is just natural and convenient when you don't have to be too strict.

    I really like ovid's comparison of the null object to the relational NULL BTW: sometimes you don't want the absence of some data to stop you, and you don't want to (and you should not have to) write a special case to handle it.