the $:version and such just actually goes
to the symbol table to get it's stuff.
However, it makes the MOP more complete.
+ ** API CHANGE **
+ - The &create method now requires that all
+ but the package name now is passed in as
+ named parameters. See docs for more info.
+ - updated docs and tests for this
* Class::MOP::Object
- added &dump method to easily Data::Dumper
which do not store things in the instance
- added the %:methods attribute definition to
the bootstrap
+
+ ~ lots of misc. test cleanup
0.33 Sat. Aug. 19, 2006
* Class::MOP::Class
sub create_anon_class {
my ($class, %options) = @_;
my $package_name = $ANON_CLASS_PREFIX . ++$ANON_CLASS_SERIAL;
- return $class->create($package_name, '0.00', %options);
+ return $class->create($package_name, %options);
}
# NOTE:
# creating classes with MOP ...
sub create {
- my ($class, $package_name, $package_version, %options) = @_;
+ my $class = shift;
+ my $package_name = shift;
+
(defined $package_name && $package_name)
|| confess "You must pass a package name";
+
+ (scalar @_ % 2 == 0)
+ || confess "You much pass all parameters as name => value pairs " .
+ "(I found an uneven number of params in \@_)";
+
+ my (%options) = @_;
+
my $code = "package $package_name;";
- $code .= "\$$package_name\:\:VERSION = '$package_version';"
- if defined $package_version;
+ $code .= "\$$package_name\:\:VERSION = '" . $options{version} . "';"
+ if exists $options{version};
+ $code .= "\$$package_name\:\:AUTHORITY = '" . $options{authority} . "';"
+ if exists $options{authority};
+
eval $code;
confess "creation of $package_name failed : $@" if $@;
+
my $meta = $class->initialize($package_name);
$meta->add_method('meta' => sub {
# or use this to actually create classes ...
- Class::MOP::Class->create('Bar' => '0.01' => (
+ Class::MOP::Class->create('Bar' => (
+ version => '0.01',
superclasses => [ 'Foo' ],
attributes => [
Class::MOP:::Attribute->new('$bar'),
=over 4
-=item B<create ($package_name, ?$package_version,
+=item B<create ($package_name,
+ version =E<gt> ?$version,
+ authority =E<gt> ?$authority,
superclasses =E<gt> ?@superclasses,
methods =E<gt> ?%methods,
attributes =E<gt> ?%attributes)>
This returns a B<Class::MOP::Class> object, bringing the specified
-C<$package_name> into existence and adding any of the
-C<$package_version>, C<@superclasses>, C<%methods> and C<%attributes>
-to it.
+C<$package_name> into existence and adding any of the C<$version>,
+C<$authority>, C<@superclasses>, C<%methods> and C<%attributes> to
+it.
=item B<create_anon_class (superclasses =E<gt> ?@superclasses,
methods =E<gt> ?%methods,
my $attr = $attrs->[$index];
my $default;
if ($attr->has_default) {
+ # NOTE:
+ # default values can either be CODE refs
+ # in which case we need to call them. Or
+ # they can be scalars (strings/numbers)
+ # in which case we can just deal with them
+ # in the code we eval.
if ($attr->is_default_a_coderef) {
$default = '$attrs->[' . $index . ']->default($instance)';
}
else {
$default = $attrs->[$index]->default;
+ # make sure to quote strings ...
unless (looks_like_number($default)) {
$default = "'$default'";
}
- # TODO:
- # we should use Data::Dumper to
- # output any ref's here, obviously
- # we cannot handle Scalar refs, but
- # it should work for Array and Hash
- # refs pretty well.
}
}
$meta_instance->inline_set_slot_value(
legend:
..(is an instance of)..>
- --(is a subclass of)-->
+ --(is a subclass of)--->
A deeper discussion of this model is currently beyond the scope of
this documenation.
=item B<dump (?$max_depth)>
+This will C<require> the L<Data::Dumper> module and then dump a
+representation of your object. It passed the C<$max_depth> arg
+to C<$Data::Dumper::Maxdepth>. The default C<$max_depth> is 1,
+so it will not go crazy and print a massive bunch of stuff.
+Adjust this as nessecary.
+
=back
=head1 AUTHORS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
-=cut
\ No newline at end of file
+=cut
use strict;
use warnings;
-use Test::More tests => 16;
+use Test::More tests => 17;
BEGIN {
use_ok('Class::MOP');
Class::MOP::Object
Class::MOP::Package
/ ],
- '... got all the metaclass names');
\ No newline at end of file
+ '... got all the metaclass names');
+
+is_deeply(
+ [ map { $_->meta->identifier } sort { $a cmp $b } Class::MOP::get_all_metaclass_names() ],
+ [
+ "Class::MOP::Attribute-" . $Class::MOP::Attribute::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Class-" . $Class::MOP::Class::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Instance-" . $Class::MOP::Instance::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Method-" . $Class::MOP::Method::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Module-" . $Class::MOP::Module::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Object-" . $Class::MOP::Object::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Package-" . $Class::MOP::Package::VERSION . "-cpan:STEVAN",
+ ],
+ '... got all the metaclass identifiers');
+
+
+
\ No newline at end of file
use strict;
use warnings;
-use Test::More tests => 19;
+use Test::More tests => 25;
use Test::Exception;
BEGIN {
package Bar;
our @ISA = ('Foo');
+
+ our $AUTHORITY = 'cpan:JRANDOM';
}
my $Foo = Foo->meta;
is($Foo->version, '0.01', '... Foo->version == 0.01');
is($Bar->version, undef, '... Bar->version == undef');
+is($Foo->authority, undef, '... Foo->authority == undef');
+is($Bar->authority, 'cpan:JRANDOM', '... Bar->authority == cpan:JRANDOM');
+
+is($Foo->identifier, 'Foo-0.01', '... Foo->identifier == Foo-0.01');
+is($Bar->identifier, 'Bar-cpan:JRANDOM', '... Bar->identifier == Bar-cpan:JRANDOM');
+
is_deeply([$Foo->superclasses], [], '... Foo has no superclasses');
is_deeply([$Bar->superclasses], ['Foo'], '... Bar->superclasses == (Foo)');
# create a class using Class::MOP::Class ...
my $Baz = Class::MOP::Class->create(
- 'Baz' => '0.10' => (
+ 'Baz' => (
+ version => '0.10',
+ authority => 'cpan:YOMAMA',
superclasses => [ 'Bar' ]
));
isa_ok($Baz, 'Class::MOP::Class');
is($Baz->name, 'Baz', '... Baz->name == Baz');
is($Baz->version, '0.10', '... Baz->version == 0.10');
+is($Baz->authority, 'cpan:YOMAMA', '... Baz->authority == YOMAMA');
+
+is($Baz->identifier, 'Baz-0.10-cpan:YOMAMA', '... Baz->identifier == Baz-0.10-cpan:YOMAMA');
is_deeply([$Baz->superclasses], ['Bar'], '... Baz->superclasses == (Bar)');
# ... test our class creator
my $Bar = Class::MOP::Class->create(
- 'Bar' => '0.10' => (
+ 'Bar' => (
superclasses => [ 'Foo' ],
methods => {
foo => sub { 'Bar::foo' },
use_ok('Class::MOP');
}
-my $Point = Class::MOP::Class->create('Point' => '0.01' => (
+my $Point = Class::MOP::Class->create('Point' => (
+ version => '0.01',
attributes => [
Class::MOP::Attribute->new('$.x' => (
reader => 'x',
}
));
-my $Point3D = Class::MOP::Class->create('Point3D' => '0.01' => (
+my $Point3D = Class::MOP::Class->create('Point3D' => (
+ version => '0.01',
superclasses => [ 'Point' ],
attributes => [
Class::MOP::Attribute->new('$:z' => (
is($baz_meta->name, 'Baz', '... baz_meta->name == Baz');
isnt($baz_meta, $bar_meta, '... Baz->meta != Bar->meta');
-isnt($baz_meta, $foo_meta, '... Baz->meta != Foo->meta');
\ No newline at end of file
+isnt($baz_meta, $foo_meta, '... Baz->meta != Foo->meta');
+
use strict;
use warnings;
-use Test::More tests => 52;
+use Test::More tests => 49;
use Test::Exception;
BEGIN {
dies_ok {
Class::MOP::Class->has_package_symbol('foo');
} '... has_package_symbol dies as expected';
-
- dies_ok {
- Class::MOP::Class->has_package_symbol('&foo');
- } '... has_package_symbol dies as expected';
}
{
dies_ok {
Class::MOP::Class->get_package_symbol('foo');
- } '... get_package_symbol dies as expected';
-
- dies_ok {
- Class::MOP::Class->get_package_symbol('&foo');
- } '... get_package_symbol dies as expected';
+ } '... get_package_symbol dies as expected';
}
{
dies_ok {
Class::MOP::Class->remove_package_symbol('foo');
} '... remove_package_symbol dies as expected';
-
- dies_ok {
- Class::MOP::Class->remove_package_symbol('&foo');
- } '... remove_package_symbol dies as expected';
}
predicate => 'has_test'
));
- my $Bar = Class::MOP::Class->create('Bar' => '0.01');
+ my $Bar = Class::MOP::Class->create('Bar');
isa_ok($Bar, 'Class::MOP::Class');
$Bar->add_attribute($attr);
use strict;
use warnings;
-use Test::More tests => 85;
+use Test::More tests => 89;
use File::Spec;
+use Scalar::Util 'reftype';
BEGIN {
use_ok('Class::MOP');
my $foo = Foo->new();
isa_ok($foo, 'Foo');
+is(reftype($foo), 'SCALAR', '... Foo is made with SCALAR');
+
can_ok($foo, 'foo');
can_ok($foo, 'has_foo');
can_ok($foo, 'get_bar');
my $foo2 = Foo->new();
isa_ok($foo2, 'Foo');
+is(reftype($foo2), 'SCALAR', '... Foo is made with SCALAR');
+
ok(!$foo2->has_foo, '... Foo2::foo is not defined yet');
is($foo2->foo(), undef, '... Foo2::foo is not defined yet');
is($foo2->get_bar(), 'FOO is BAR', '... Foo2::bar has been initialized');
isa_ok($bar, 'Bar');
isa_ok($bar, 'Foo');
+is(reftype($bar), 'SCALAR', '... Bar is made with SCALAR');
+
can_ok($bar, 'foo');
can_ok($bar, 'has_foo');
can_ok($bar, 'get_bar');
isa_ok($baz, 'Foo');
isa_ok($baz, 'Baz');
+is(reftype($baz), 'SCALAR', '... Bar::Baz is made with SCALAR');
+
can_ok($baz, 'foo');
can_ok($baz, 'has_foo');
can_ok($baz, 'get_bar');
use strict;
use warnings;
-use Test::More tests => 65;
+use Test::More tests => 69;
use File::Spec;
+use Scalar::Util 'reftype';
BEGIN {
use_ok('Class::MOP');
my $foo = Foo->new();
isa_ok($foo, 'Foo');
+is(reftype($foo), 'ARRAY', '... Foo is made with ARRAY');
+
can_ok($foo, 'foo');
can_ok($foo, 'has_foo');
can_ok($foo, 'get_bar');
my $foo2 = Foo->new();
isa_ok($foo2, 'Foo');
+is(reftype($foo2), 'ARRAY', '... Foo is made with ARRAY');
+
ok(!$foo2->has_foo, '... Foo2::foo is not defined yet');
is($foo2->foo(), undef, '... Foo2::foo is not defined yet');
is($foo2->get_bar(), 'FOO is BAR', '... Foo2::bar has been initialized');
isa_ok($bar, 'Bar');
isa_ok($bar, 'Foo');
+is(reftype($bar), 'ARRAY', '... Bar is made with ARRAY');
+
can_ok($bar, 'foo');
can_ok($bar, 'has_foo');
can_ok($bar, 'get_bar');
isa_ok($baz, 'Foo');
isa_ok($baz, 'Baz');
+is(reftype($baz), 'ARRAY', '... Bar::Baz is made with ARRAY');
+
can_ok($baz, 'foo');
can_ok($baz, 'has_foo');
can_ok($baz, 'get_bar');