I understand what you're saying about managing method names and
keeping things orthogonal as the API evolves. I think your "literal"
method is a fine idea. For now, Perl::Critic has a perfectly adequate
workaround.
-Jeff
[adam@phase-n.com - Sat Oct 1 08:03:38 2005]:
Show quoted text> Let me briefly explain the API situation.
>
> PPI, as you are well aware, is an enormous fucking API.
>
> The problem I've found, and the reason why I've held back on a lot of
> these sorts of analysis methods, is that if you use a method name for
> say Token::Number, then it has a specific meaning and so it can't be
> reused in clashing classes.
>
> That means it can't be used in ::Token, or ::Node, or ::Element, or
in
Show quoted text> anything else below ::Element where you may one day want to "push"
the
Show quoted text> methods higher up the API towards ::Element from some lower subclass.
>
> For something with 50 classes, ALL of which I can think of two or
> three
> useful methods to have, it's a nightmare. Do I show all the very
> specific ones down under ->is_something? (my current preference).
>
> Do I just start assigning names and hope for the best (big doubts).
>
> What I think the best strategy might be is this.
>
> 1) For anything that can be seen as being general, pick a REALLY
> specific and general definition, and jam it all the way up as close
to
Show quoted text> ::Element as possible, preferably IN element.
>
> If you don't have implementations of the method ready for all 50
> classes, you ONLY document it in the ones that you have done it for,
> but
> treat the method as "marked for greatness" and assume it will get
> implement over the next few point releases. Or provide a useless
> default
> in ::Element...
>
> And then we combine those with extremely specific method names for
the
Show quoted text> exotics so that there no risk stealing a potential name from a more
> global one.
>
> Get the idea?
>
> As for what you want, I suspect that it fits into my plan for
> ->literal.
>
> That is, you take a token, or a statement, or what have you, and IF
> that
> code is treated by perl itself as a literal value, then PPI will
> construct and return exactly that value.
>
> So you get the following.
>
> my $code = "{ foo => 'bar' }";
> my $Document = PPI::Document->new( \$code );
>
> is_deeply( $Document->child(0)->literal, { foo => 'bar' }, '->literal
> works as expected' );
>
> The only tricky bit is error conditions... you either have to return
> EVERYTHING by reference and treat return undef as error, or you die
on
Show quoted text> error. I'm not so fond of that, since I made a design decision to go
> with return undef on error, little to no list/wantarray returns, and
> to
> not use exceptions.
>
> But by-reference sucks ass, since you'd be calling ->literal for your
> children, unwrapping the references, building your thing, and then
> re-referencing it again, recursively :(
>
> So what we might do is define the "Literal" feature as a pair of
> methods. ->is_literal returns true/false on whether it is possible
for
Show quoted text> an Element to be made literal, and then ->literal does the actual
> conversion, throwing a die/exception on failure.
>
> That way the only exceptions should be for people that don't read the
> manual and didn't do a ->is_literal first. And we don't owe those
> people
> very much.
>
> So... would ->literal (returning EXACTLY what Perl would otherwise
see
Show quoted text> a
> number as) be sufficient for your need?
>
> The tricky bit is handling the weird number types without just
getting
Show quoted text> pissed at how hard it is and just using string "eval". :)
>
> But then no string eval anywhere means no potential to even have code
> injection, and PPI's promise to never allow code injection is a core
> promise.
>
> Adam K
>
> Guest via RT wrote:
> > This message about PPI was sent to you by guest <> via rt.cpan.org
> >
> > Full context and any attached attachments can be found at:
> > <URL:
https://rt.cpan.org/Ticket/Display.html?id=14868 >
> >
> > Adam-
> >
> > What do you think of a "value" method for Token::Number, which
would
Show quoted text> remove the underscores, if there are any?
> >
> > sub value {
> > my $value = $_[0]->content();
> > return eval $value;
> > }
> >
> > Additionaly, you could overload Token::Number to DWIM in numeric
> contexts.
> >
> > $num = $doc->find_first('Token::Number');
> > print $num + 42;
> >
> > -Jeff