Class::Dummy?

Ovid on 2008-01-31T11:54:50

If I want to serialize arbitrary classes with Bermuda, I need to make arbitrary classes (and instances of them. I looked for something useful, but I'm not seeing it. Currently I'm writing the following:

ok my $dummy = Class::Dummy->new(
    package => 'Foo::Bar',
    methods => {
        first_name => 'bob',
        last_name  => 'marley',
        aref       => [ 1,2,3 ],
        list       => sub { ( 3, 4, 5 ) },
        full_name  => sub {
            my $self = shift;
            return join ' ' => map { $self->$_ } qw/ first_name last_name /;
        },
    };
), '... creating a dummy class should succeed';

isa_ok $dummy, 'Class::Dummy', '... and the object it returns';
can_ok $dummy, 'first_name';
is $dummy->first_name, 'bob';

Please let me know if this already exists.


Inner classes!

AndyArmstrong on 2008-01-31T12:03:09

You could nearly call that Class::Inner and have it work like Java's inner classes :)

Which IMO might be a useful thing. Inner classes definitely have their uses - maybe more so in Java.

Re:Inner classes!

Ovid on 2008-01-31T12:09:41

I was thinking of this more as a testing tool so that I could generate fixtures on the fly and embed them in tests:

my $instance   = Class::Dummy->new(\%interface);
my @islands    = @yaml_strings;
my $serialized = Bermuda::Test->serialize($instance, @islands);

# a bunch of tests

A persistent problem with test suites is having fixtures embedded in files and the poor programmer has to pop between several files to see them. That also means that a change to one fixture possibly means a change to a wide variety of tests (I keep getting bitten by this). With this, all fixture data can be in each test. This makes unit tests easier to manage.

Re:Inner classes!

AndyArmstrong on 2008-01-31T12:28:43

Sorry - being terse today :)

I realised what it was for but it occurred to me that it might sometimes be useful outside of tests.

Re:Inner classes!

Ovid on 2008-01-31T13:18:44

Maybe I should rename it then? It really does seem like a useful testing tool (it's already making my life easier), but perhaps others could use it. Does Class::Temp sound like a good name? It would be very useful when you find yourself passing around hashrefs but you hate locked hashes.

Re:Inner classes!

AndyArmstrong on 2008-01-31T13:38:46

I think Class::Inner is a similar but different thing that you can release once you get all the other interesting things you're working on done :)

Re:Inner classes!

Ovid on 2008-01-31T13:46:59

And along the lines of what I said earlier, here's my first test case with it:

#!/usr/bin/perl

use strict;
use warnings;

use lib 'lib', 't/lib';
use Test::Most 'no_plan'; # tests => 1;
use Test::XML;
use Bermuda::Test;
use Bermuda::XML;
use Class::Dummy;

my $dummy = Class::Dummy->new(
    package => 'Some::Class',
    methods => {
        name => 'Victoria',
        email => sub {
            my $self = shift;
            my %email = (
                personal => 'victoria@example.com',
                work     => 'victoria@some_company.com',
            );
            return $email{+shift};
        },
        to_xml => sub {
            require Some::Class::Bermuda;
            require Bermuda::XML;
            return Bermuda::XML->new->render(
                Some::Class::Bermuda->fetch_data(shift)
            );
        },
    }
);
my $island = <<'END_ISLAND';
---
package: Some::Class
island: dummy
name: dummy
attributes:
  name:
    type: string
elements:
  - personal_email
  - type: string
    method: email('personal')
  - work_email
  - type: string
    method: email('work')
END_ISLAND

Bermuda::Test->build($island);

my $expected = <<'END_XML';
<?xml version="1.0" encoding="utf-8"?>
<dummy name="Victoria">
  <personal_email>victoria@example.com</personal_email>
  <work_email>victoria@some_company.com</work_email>
</dummy>
END_XML
is_xml $dummy->to_xml, $expected,
    'Methods with args should correctly serialize to XML';

To my mind, that shows me that the &to_xml method is problematic. I can automate that. People need to be able to create a Bermuda project and then make it simple by dropping this into their classes:

package Some::Company::Invoice;

use Class::Trait 'Some::Company::Bermuda';

And then the Some::Company::Invoice class automatically gets a &to_xml method. Already have a &to_xml method?

package Some::Company::Invoice;

use Class::Trait (
    'Some::Company::Bermuda' => {
        alias => { to_xml => 'as_xml' },
    }
);

some options

rjbs on 2008-01-31T14:16:55

There's Class::Generate, which looks pretty weird to me. I use (wrote) Package::Generator, which has no method sugar. You can use Class::MOP, too, as seen here:

http://groups.google.com/group/perl.perl5.porters/msg/b05428a97a7a91e4

Re:some options

Ovid on 2008-01-31T14:24:08

Ah, that looks pretty interesting!

Package::FromData

rj on 2008-02-03T12:26:20

http://search.cpan.org/user/jrockway/Package-FromData-0.01/lib/Package/FromData.pm/ looks very similar.