On tirsdag 25 januar 2005, 10:35, Kake L Pugh wrote:
Ahh, I get it now. It's not clear from the name that ->format does initialisation and leaves things behind in the formatter for ->document and ->fragment to act on.
Yup, it is not quite clear.
It also seems possible that the ability to return a fragment rather than a document (or vice versa) could depend on the input as well as the class of the formatter.
Hmmm, it could, there are many unknowns when you try to create something that is supposed to work over a wide array of things... But I suspect that usually you can smack something around any string to get a whole document...
And it feels wrong to me that information about the last input is stored in the formatter. If you want to format something else before you're done with the last thing, either the work is lost or you need to create a new formatter, and that feels very wrong.
Hmmm, I didn't understand that...
If you format $foo->format("the *foo* of bar") you can always call $foo->title anywhere, so there is nothing lost there. If OTOH you want to $baz->format("barring _foo_"), yes you should create a new object, I see that as a good thing. Nothing is lost since all the hard work must be done separately for each string anyway. I think I learnt something about this in OO class a while ago... :-)
Finally, it seems that there really should be some _programmatic_ way to find out whether we can get a fragment (or a document) back from our input.
Hm, well, that was the idea with requiring that it should return undef if it couldn't return what we wanted, you could check the return value, like...:
With those points in mind, how about we change ->format to ->parse, and return an object:
my $parsed = $formatter->parse( $string ); if ( $parsed->can( "document" ) ) { print $parsed->as_document; } else { print "<html><head><title>My Doc</title></head><body>", $parsed->as_fragment, "</body></html"; }
my $formatter = Formatter::Foo::Bar->format( $string ); if ( $formatter->document ) { print $formatter->document; } else { print "<html><head><title>My Doc</title></head><body>", $formatter->fragment, "</body></html"; }
While some way to find the capabilities of a formatter is nice, I can't really see any advantage to is in this case.
But then, when we started discussing this, I realized that it would be better just to demand that when you call $formatter->document; you're done, you can trust that you'll get something. It may not be the best, but it is something you can use. To take the worries off of the user.
This allows expansion of the API like so:
if ( $parsed->can( "interwiki_links" ) ) { @links = $parsed->interwiki_links; }
Yup. Well, I agree that something to check capabilities of the object is useful, but only in the cases where it is much more expensive to just do it than find out if we have a capability. I suspect that in most cases here, it'll be pretty cheap to find the links, so testing on $formatter->interwiki_links would be sufficient. Formatters that know they do expensive operations can cache their result transparently.
$parsed would be of class something like Formatter::Parsed::UseMod.
That would be a pretty radical departure from the architecture we are aiming at, which is a simple Formatter::To::From between formats. And I'm sort of running out on time... :-(
The way this fits in with Wiki::Toolkit is that when a node is created, its content is parsed by a Formatter, and the $parsed object is stored in the node object.
OK!
I've been discussing with jerakeen offlist, and what we have come to is to drop the new method, make format the constructor, which returns the object, not the string. Then, the document and fragment methods return the strings. OK?
Cheers,
Kjetil