On 14/03/03 13:20 -0700, why the lucky stiff wrote:
> On Friday 14 March 2003 12:48 pm, Brian Ingerson wrote:
> > It's interesting because Syck is more than a parser, but less than a
> > loader. But you could easily build a push/pull wrapper over it, or build
> > a loader out of it. I kinda like it. (Especially if it works!)
> >
> 
> You can turn implicit typing on or off as you parse, so it really strives to 
> be both a parser and a loader, if you want it to.  The parsing of implicit 
> types is separate, so you can use that independantly as well.  (In an XML 
> parser, for instance. :D)

So how do you think that specific type handling is going to be
cross-language? If you can fully load a !foo {} from Syck, there's a
problem. Because it assuredly won't work from perl. Your syck node
should contain a kind and a type. And the program using Syck should call
the class method to create the foo object.

I would argue against putting Ruby only features in Syck. Put those in a
separate C library.

> 
> > I could actually see doing the Perl extension to Syck as
> > YAML::Parser::Syck or YAML::Loader::Syck. Eventually I'd want both. I
> > think I'll start with the Loader though.
> >
> 
> YAML.rb + Syck sports similiar fashion.  YAML::Loader::Syck is the base class 
> of YAML::Parser::Syck.  A different handler is used in the loader and 
> implicits are turned off.

Actually I do things a bit differently in Perl. A YAML::Parser is
definitely not a subclass of YAML::Loader. A Loader object contains a
parser object, which keeps them totally orthoganal. So my end user
interface is something like this:

    use YAML;

    $y = YAML->new;
    $y->loader('YAML::Loader::Standard');
    $y->loader->parser('YAML::Parser::Syck');

    $y->loader->parser->string(<<END_YAML);
    ---
    foo: barney
    END_YAML
    
    $data = $y->loader->next;

That's long for:

    use YAML;

    $YAML::Loader = 'YAML::Loader::Standard';
    $YAML::Parser = 'YAML::Parser::Syck';

    $data = Load <<END_YAML;
    ---
    foo: barney
    END_YAML

The nice thing is that I can switch out any component. When this really
pays is when end users want to create their own Loaders. Let me show you
how this would happen in Perl:

Say that a user needed a Loader that loaded scalars as strings except
for dates and currency. Say they also wanted to load strings that looked
like RGB values as color objects:

This is what their entire Perl YAML Loader module would look like:

    package My::YAML::Loader;

    # set up inheritance
    use base 'YAML::Loader::Date',
             'YAML::Loader::Currency',
             'YAML::Loader::Standard';

    # associate this class with certain implicit values
    sub yaml_match {
        my ($self, $node) = @_;
        # match strings like 'ffcc55'
        return ($node->value =~ /[0-9a-f]{6}/); 
    }

    sub yaml_load {
        my ($self, $node) = @_;
        return Color->new($node->value);
    }

    1;

And they use it like this:

    use YAML;

    $YAML::Loader = 'My::YAML::Loader';

    $data = Load <<END_YAML;
    ---
    red: FF0000
    white: FFFFFF
    blue: 0000FF
    END_YAML

I hope that gives a clearer indication of where I want to go with this.

Cheers, Brian