Jonathon Rockway throws down the gauntlet on Object::Tiny

brian_d_foy on 2007-09-04T11:33:00

In what I'm sure he meant to be a throwaway rhetorical question, Jonathon asks:

> Why bother when Class::Accessor::* already does the same thing?
OH IT'S SO ON! :)

So after writing some quick benchmarks (in the examples directory of the new Object::Tiny 1.03) and doing some investigations and tweaking (stole a small trick from Class::Accessor::Fast to make my accessors slightly faster), here is the answer to Jonathon's question, from the Object::Tiny docs.

------------------------------------------------------------------------------

Why bother when Class::Accessor::* already does the same thing?

As a class builder, Object::Tiny inevitably is compared to
Class::Accessor and related modules. They seem so similar, so why would
I reimplement it?

The answer is that for experienced developers that don't need or want
hand-holding, Object::Tiny is just outright better, faster or cheaper
on every single metric than Class::Accessor::Fast, which
is the most comparable member of the Class::Accessor::* family.

Object::Tiny is 93% smaller than Class::Accessor::Fast

Class::Accessor::Fast requires about 125k of memory to load.

Object::Tiny requires about 8k of memory to load.

Object::Tiny is 75% more terse to use than Class::Accessor::Fast

Using Object::Tiny requires the least possible number of keystrokes
(short of making the actual name Object::Tiny smaller).

And it requires no ugly constructor methods.

I mean really, what sort of a method name is 'mk_ro_accessors'. That sort
of thing went out of style in the early nineties.

Using Class::Accessor::Fast...

  package Foo::Bar;
  use base 'Class::Accessor::Fast';
  Foo::Bar->mk_ro_accessors(qw{ foo bar baz });
Using Object::Tiny...

  package Foo::Bar;
  use Object::Tiny qw{ foo bar baz };
You'll note I've been a little generate there. The alternative to
Repeating Yourself (which is one of those things you Don't do) is to
use the longer (in this case) and even uglier __PACKAGE__ compiler flag.

Further, Object::Tiny lets you pass your params in directly, without
having to wrap them in an additional HASH reference that will just be
copied ANYWAY inside the constructor.

Using Class::Accessor::Fast...

  my $object = Foo::Bar->new( {
      foo => 1,
      bar => 2,
      baz => 3,
  } );
Using Object::Tiny...

  my $object = Foo::Bar->new(
      foo => 1,
      bar => 2,
      baz => 3,
  );
Object::Tiny constructors are 110% faster than Class::Accessor::Fast

Object::Tiny accessors are identical in speed to Class::Accessor::Fast
accessors, but Object::Tiny constructors are TWICE as fast as
Class::Accessor::Fast constructors, DESPITE C:A:Fast forcing you to pass
by reference (which is typically done for speed reasons).

  Benchmarking constructor plus accessors...
               Rate accessor     tiny
  accessor 100949/s       --     -45%
  tiny     182382/s      81%       --
 
  Benchmarking constructor alone...
               Rate accessor     tiny
  accessor 156470/s       --     -54%
  tiny     342231/s     119%       --
 
  Benchmarking accessors alone...
             Rate     tiny accessor
  tiny     81.0/s       --      -0%
  accessor 81.0/s       0%       --
Object::Tiny pollutes your API 95% less than Class::Accessor::Fast

Object::Tiny adds two methods to your class, new and import. The
new constructor is so trivial you can just ignore it and use your own
if you wish, and the import will shortcut and do nothing (it is used to
implement the "use Object::Tiny qw{ foo bar baz };" syntax itself).

So if you make your own import, you can ignore the Object::Tiny one.

Class::Accessor::Fast isn't quite as light, adding all sorts of useless
extra public methods. Worse, it adds them as public methods!!!

Why on earth would you want to allow your users to add more accessors to the classes they are using at run-time?

Here's what the classes used in the benchmark end up like.

    DB<1> use Class::Inspector
 
    DB<2> x Class::Inspector->methods('Foo_Bar_Tiny');
  0  ARRAY(0xfda780)
     0  'bar'
     1  'baz'
     2  'foo'
     3  'import'
     4  'new'
 
    DB<3> x Class::Inspector->methods('Foo_Bar_Accessor');
  0  ARRAY(0xfdb3c8)
     0  '_bar_accessor'
     1  '_baz_accessor'
     2  '_carp'
     3  '_croak'
     4  '_foo_accessor'
     5  '_mk_accessors'
     6  'accessor_name_for'
     7  'bar'
     8  'baz'
     9  'best_practice_accessor_name_for'
     10  'best_practice_mutator_name_for'
     11  'follow_best_practice'
     12  'foo'
     13  'get'
     14  'make_accessor'
     15  'make_ro_accessor'
     16  'make_wo_accessor'
     17  'mk_accessors'
     18  'mk_ro_accessors'
     19  'mk_wo_accessors'
     20  'mutator_name_for'
     21  'new'
     22  'set'
Object::Tiny adds 2 extra methods to your class.

Class::Accessor adds 16 extra methods, plus one extra for every accessor.

B

When you call B it isn't treated as some
sort of complete specification for the class, it's just a list of accessors
you want made for you.

So if you want to customize foo you don't need to get into contortions with
"pure" base classes or calling alternate internal methods. Just make your own
foo method and remove foo from the list passed to the use call.

Object::Tiny is more back-compatible than Class::Accessor::Fast

Class::Accessor::Fast has a minimum Perl dependency of 5.005002.

Object::Tiny has a minimum Perl dependency of 5.004.

Object::Tiny has no module dependencies whatsoever

Object::Tiny does not load ANYTHING at all outside of it's own single .pm file.

So Object::Tiny will never get confused in odd situations due to old or weird
versions of other modules (Class::Accessor::Fast has a dependency on base.pm,
which has some caveats of it's own).

--------------------------------------------------------------------

So yes, Object::Tiny kicks Class::Accessor's ass all over the interpreter.

Now personally, the question I think is more relvant is...

> If all you want is a bunch of simple accessors, why use a helper class at all?

The answer is convenience. And that's why Object::Tiny exists, for times when I'm lazy and in a hurry, and I just want to press less buttons to get the same thing as I would have typed anyway.

And for me, Class::Accessor doesn't deliver on that need.


I'm convinced!

jrockway on 2007-09-04T04:40:41

Thanks for the response :)

BTW, s/on/an/ in my name.

Re:I'm convinced!

yDNA Barak on 2007-09-04T20:14:58

Janathon?

Looks great!

Ovid on 2007-09-04T05:49:43

Regrettably, it still requires a blessed hashref, but that's a small price to pay for a prototyping tool.

Passing hashref to constructor

melo on 2007-09-04T10:10:44

Hi, regarding

Further, Object::Tiny lets you pass your params in directly, without having to wrap them in an additional HASH reference that will just be copied ANYWAY inside the constructor.
and

Object::Tiny accessors are identical in speed to Class::Accessor::Fast accessors, but Object::Tiny constructors are TWICE as fast as Class::Accessor::Fast constructors, DESPITE C:A:Fast forcing you to pass by reference (which is typically done for speed reasons).

Speed is not the only reason, and I believe its not the mains reason even.

My reason to always pass hashrefs is that if I leave out one of the arguments, the error message from perl will tell me the exact line number where I made the mistake, and not the line inside your constructor where you assign @_ to an hash (the common approach).

Having said that, if your constructor checks for a even number of parameters and croaks (or Carp::Clan croaks), then the message will show the correct line number again.

I haven't check the Object::Tiny yet, but I will. And this will probably the first think I'll look for :)

The module looks great BTW.

Re:Passing hashref to constructor

mr_bean on 2007-09-05T02:42:01

..the error message from perl will tell me the exact
      line number where I made the mistake, and not the line inside your
      constructor where you assign @_ to an hash (the common approach).

That's what Perl Best Practices recommends too, I think,
although it looks terrible.

Re:Passing hashref to constructor

melo on 2007-09-05T09:57:40

Yes it is... As for the syntax, it grows on you.

But truth be told, there is no need to use that trick to get the proper error line. If module authors that accept hashes add this line:

    croak('FATAL: odd number of parameters, ') if @_ % 2;

(Use Carp qw( croak ) at the top also)

It would also work.

Best regards,

Object::Tiny accessors are read-only

dagolden on 2007-09-04T12:12:01

Unfortunately, Object::Tiny accessors are read-only.

So there's one little thing that Class::Accessor has over Object::Tiny. (For about 30 seconds until Adam goes and adds it.)

Otherwise, Object::Tiny++

Re:Object::Tiny accessors are read-only

Alias on 2007-09-04T16:58:59

Accessors ARE read-only...

Frankly, I don't get this obsession people have with mutators.

90% of the time, you want to make a data object of some sort with the attributes fixed at create-time.

90% of the time, it makes little to no sense to have values changing after the object is created.

This sort of thing is silly.

my $object = Foo->new;
$object->param1('foo');
$object->param2('bar');


It leaves the code in a transitional state that may will be illegal.

FAR better to just provide it to the constructor, ensure the object is legal, and then keep it that way.

So in this case, no Object::Tiny won't be getting read-write accessors. It's feature bloat :)

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-04T18:57:47

It’s not like it’s hard to write them manually. What O::T provides is just a simple hash-bashed object after all.

Re:Object::Tiny accessors are read-only

Alias on 2007-09-05T00:43:34

Exactly. The times when I do need something more complex than a trivial hash-based object with simple accessors, I don't mind writing it by hand.

Re:Object::Tiny accessors are read-only

schwern on 2007-09-05T06:01:55

You're all insane.

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-05T07:26:18

> Accessors ARE read-only...
> Frankly, I don't get this obsession people have with mutators.
> 90% of the time, you want to make a data object of some sort with the attributes fixed at create-time.
> 90% of the time, it makes little to no sense to have values changing after the object is created.

I strongly disagree.

Accessors are invented to get control over accessing the object attributes. From where did you derive the restriction to read-only or write-only? I have never read such restriction in OO-related literature before.

If the user of a class starts accessing the hash elements directly, then why shouldn't he also use hash access to read them?

Re:Object::Tiny accessors are read-only

runrig on 2007-09-05T21:11:47

f the user of a class starts accessing the hash elements directly, then why shouldn't he also use hash access to read them?

So I don't make $object->tyops(). Though a tied hash would also take care of that...oh, well (without the parens, it also saves some typing)

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-06T06:55:30

Ha! I waited for this answer. :-)

So why would one protect against typos in read access but accept their chance when writing to the members?

And why don't you also want save some typing in writing?

Re:Object::Tiny accessors are read-only

Alias on 2007-09-06T07:30:32

> And why don't you also want save some typing in writing?

Because, at least for the things I write, writing generally Has Implications.

By having the object ALWAYS be valid and correct while in existance, it means both that anyone taking an object never has to check it, it is always correct.

But it also means that anything where they are writing to an attribute requires param-checking, validation, potentially deeper implication (flushing caches when you move a source directory) and so on.

Reading is a simple task, writing is not always so.

So I don't want to save typing there.

Or if I REALLY want to, I go up to something like Moose.

Re:Object::Tiny accessors are read-only

malte on 2007-09-05T17:52:48

Accessors are not read only. For a polymorphic system that allows transparent overloading of setter methods, writing to objects must be done via accessors too.

I would actually to so far as to that the initialization should use the accessors too (encapsulation of validation, rocket engine startup, etc.).

Object::Tiny should be renamed Object::Immutable::Tiny

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-05T19:16:56

I’m not sure I follow. Did I miss the fact that O::T hides the hash from you or locks it? Or does the fact that it only provides read-accessors but not mutators somehow prevent you from writing mutators? Or something? How are O::T objects immutable?

Re:Object::Tiny accessors are read-only

malte on 2007-09-05T19:32:50

Well, I follow one simple rule. I don't care about the object representation (Hashref, Arrayref, InsideOut, esoteric stuff, ...) and never access instance vars accept through accessors ... and I haven't written a simple accessor myself since 1999. So an object that doens't have setters is immutable.

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-05T21:01:13

That’s just smoke and mirrors. Someone has to create those mutators, and that someone needs to know about the underlying implementation.

It does not buy you much either. Even if you are using a method maker module to pretend not to know anything, your objects are not subclassable without knowledge of their guts any more than they would be with any other approach: subclasses must use the same method maker module to add their own accessors, so they need to need to know how the superclass is implemented. This isn’t technically any different from subclasses containing custom-written accessors that expect a hashref as the underlying implementation.

Inside-out objects are the only way out of this situation, but I kinda doubt you’ve been writing those since 1999.

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-06T07:09:13

Hm, you are basically arguing that I can subclass to add write accessors. For that, of course I need knowledge about internal representation.

But if O::T already had read/write accessors, all your subclassing would not have to fiddle with internal representation of members.

And if one argues, that I can add write accessors by myself, why not create an Object::Really::Tiny that simply does nothing but is even more faster and more lightweight? Think of all the freedom you get from the possibility to create all your functionality by simply subclassing from an empty class. That would be fun!

Am I getting sarcastic? Yes. Sorry for that. :-) Basically I mean it constructive but don't want to loose the entertaining factor of sarcasm.

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-06T12:35:43

I’m not sure what point your sarcasm is supposed to make. It misses the point entirely.

O::T is just supposed to save a bit of typing. Now how often do you need straight mutators that just assign to a variable with no validation whatsoever? If often, then something is wrong with your OO designs. If very rarely, as it should be, there’s not much point to including that functionality in O::T, since, well, it’s rarely needed.

So if you wanted to include mutator generation, it would require a way to specify validation. So either there is a validation API – which takes 5× as much code as the entire rest of the module, so you can’t call it ::Tiny anymore –, or you let the client pass in coderefs – which does not make the client code any shorter than just writing the mutator manually.

Do you see any problems with that idea yet?

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-06T14:03:07

I’m not sure what point your sarcasm is supposed to make. It misses the point entirely.

No. I don't miss the point. And especially not "entirely". I hate it when you say that. :-)

Object::Tiny is by its own doc about "Class building".

"Class building" is OO. Accessors are OO. This is a good moment to repeat my question:

Please show me literature about OO where "accessors" are introduced as a read-only concept. They are used to decouple the access to the members from their implementation (hash, array, whatever).

Now how often do you need straight mutators that just assign to a variable with no validation whatsoever?

Validation checks have nothing to do with the final step of assigning a value to a member.

We talk about the difference between

$foo->{a} = 'bar';
vs.

$foo->a('bar');
In the latter case, $foo's internal object representation can be changed from hash to whatever. In the first case not.

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-06T14:47:16

So what? The only code that should need changing when you change the internal representation is the code inside the class, anyway. So for use inside the class, non-validating mutators protect against a change that is rare and involves only code that you have control over. What’s the point?

And exposing non-validating mutators to API clients is bad. I’m not sure whether you are confusing literature about Java with literature about OO, but OO is not about structs with loosely associated procedures. Objects that have no behaviour, only state, are a sign of broken OO design.

So is $foo->a('bar'); supposed to do validation or not? If not, it’s either mostly pointless or you have a problem. If yes, you have no way of easily specifying validation, at least without bloating O::T.

So the point of generating mutators is…?

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-06T15:15:33

So what? The only code that should need changing when you change the internal representation is the code inside the class, anyway.
This is plain wrong, at least for write access to members, which is what we are talking about. But let's start at the beginning.

Even if I had read too many Java books, the "accessor" thing is quite common. To make it more understandable I will try to explain what I understand as (one aspect of) OO. In my OO world I can change the internal representation e.g. from hashes into an ordered array. My member "a" becomes, for instance, the 5th element of a blessed array. Without write accessors the user of my class has to change his code from

  $foo->{a} = 'bar';
into

  $foo->[4] = 'bar';
If I had an write accessor "a" the user of my class can always write

  $foo->a('bar')';
independently from whether I implemented/overloaded it as

package Foo;
sub a {
  my $self = shift;
  my $arg  = shift;
  $self->{a} = $arg;
}
or

package Foo;
sub a {
  my $self = shift;
  my $arg  = shift;
  $self->[4] = $arg;
}
That's what accessors are about. Most of the time they are hashes in the Perl world, of course. That's why it is nice to have modules that provide this, Class::MethodMaker, Class::Accessors. Once I have accessors, it's easy to subclass them or overwrite or whatever to change the behaviour of "a".

I can even add a validation to the class, and I can do this transparently so that even then the user of my class does not need to think about the API.

So now you may explain your OO.

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-17T08:20:18

Never ever did I say the user should write $foo->{a} = 'bar';. That’s wrong. But $foo->a('bar')'; is just as wrong in terms of OO design. It increases encapsulation a tiny bit, but it does not decrease coupling. Mutators that do not validate the value they are passed are almost never necessary in a good OO design.

And if you do need such a mutator, then knowing that $self is a hash ref and using it to implement the mutator is not a problem, since that knowledge remains isolated to the class itself.

So there’s not much point in bloating the API of a hashref-based class builder with mutator support.

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-17T09:27:02

Could you please name a particular book or article where I can learn more about your often cited coupling of writing to members with forced validation provided by a general base mechanism? I'm really willing to learn about that.

In the meantime, I stick with Class::Accessor.

Re:Object::Tiny accessors are read-only

Alias on 2007-09-07T08:34:54

In the entire time I have been writing Perl, I can remember changing the internal object structure (from a HASH to a SCALAR ref from memory, for speed reasons) exactly twice.

I have no problem rewriting a bunch of code in that case.

Re:Object::Tiny accessors are read-only

Alias on 2007-09-06T00:20:34

Nope, it doesn't lock anything.

It's just that the DEFAULT implementation does not allow for ->method('foo'), Object::Tiny only implements ->method.

Re:Object::Tiny accessors are read-only

Aristotle on 2007-09-06T00:38:25

I knew that. My question was, uhm, socratic. :-)

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-06T07:42:15

90% of the time, it makes little to no sense to have values changing after the object is created.

This sort of thing is silly.

my $object = Foo->new;
$object->param1('foo');
$object->param2('bar');

If you would be so kind to add write accessors to Object::Tiny you could improve even your own code once you come to those last 10%, e.g. Module::CGI::Install line 130:

$self->{cgi_path} = ...

Once it had write accessors I for myself would switch to that module in favour of Class::Accessors which I currently had a closer look to in order to substitute an overblown Class::MethodMaker based module because that really pollutes my namespace.

Re:Object::Tiny accessors are read-only

Alias on 2007-09-07T08:45:41

I find your use of "Improve" interesting, mostly because it implies both that it would be better, and additionally that there is a need to make it better.

For simple module that won't accumulate a large diversity of subclasses, I have no problem whatsoever writing to the hash element directly from within the same class that defines the property itself (You'll note I work directly with it in the new constructor as well).

Also, that value can also be passed in directly.

Module::CGI::Install->new( cgi_path => '/some/path' );
This is intentional.

I did consider "write accessors" (maybe we just have a terminology mixup here, I'd call that a mutator) but I couldn't see a way to implement it concisely.

If you would like to propose a patch that allows the implementation of write accessors in 3 lines of code or less, that does not require any additional characters to be used in the line...

use Object::Tiny qw{ foo bar baz };
... then I would be happy to listen, and possibly even take the patch.

But I for one don't see any obvious way to do it, without inducing either code or API bloat (for ::Tiny's typically aggressive use of the term 'bloat')

Re:Object::Tiny accessors are read-only

schwigon on 2007-09-07T10:25:10

I find your use of "Improve" interesting, [...]

Please pardon my way of becoming personal. I originally wanted to show code that uses O::T to make it obvious what I mean and your module was the only one I found. I did not originally intend to let it sound as personal as it does, the way I phrased it in the end.

To become more concrete, what I mean, is the following patch. Full patch with tests is at http://renormalist.net/misc/object_tiny_write_accessors.patch.

diff -ur Object-Tiny-1.03/lib/Object/Tiny.pm Object-Tiny-1.04/lib/Object/Tiny.pm
--- Object-Tiny-1.03/lib/Object/Tiny.pm 2007-09-04 05:06:48.000000000 +0200
+++ Object-Tiny-1.04/lib/Object/Tiny.pm 2007-09-07 12:03:29.000000000 +0200
@@ -3,7 +3,7 @@
# use strict; # Enable during dev and testing
BEGIN {
        require 5.004;
-       $Object::Tiny::VERSION = '1.03';
+       $Object::Tiny::VERSION = '1.04';
}

sub import {
@@ -16,7 +16,7 @@
                map {
                        defined and ! ref and /^[^\W\d]\w*$/s
                        or die "Invalid accessor name '$_'";
-                       "sub $_ { return \$_[0]->{$_} }\n"
+                       "sub $_ { if (defined \$_[1]) { \$_[0]->{$_} = \$_[1] } ; return \$_[0]->{$_} }\n"
                } @_;
        die "Failed to generate $pkg" if $@;
        return 1;
It is a naive implementation, but maybe it therefore even fits to the definition of "tiny".

Re:Object::Tiny accessors are read-only

Alias on 2007-09-10T02:18:55

I have two problems with that sort of change.

1. It makes EVERY accessor writable, which is a BAD idea. I generally require that all objects are valid at all times, so allowing anything to arbitrarily change accessors is really really nasty.

2. It makes the accessors slower (I think) because of the extra conditional.

The change I was looking for was more for keeping the default read-only, but to add additional read/write accessors.

abuse of import

perrin on 2007-09-04T16:23:11

Class::Accessor has the advantage that it doesn't abuse import() to do something other than importing just to get a more compact syntax.

Re:abuse of import

Alias on 2007-09-04T17:00:26

Last time I checked though, the abuse of import is hardly considered a cardinal sin on the level of, say, adding UNIVERSAL:: methods.

Re:abuse of import

Aristotle on 2007-09-04T19:38:12

Does it matter?

In fact, since O::T creates accessors with the given names, it’s arguable whether it’s even abuse in the first place.

Re:abuse of import

perrin on 2007-09-04T19:48:59

I find it unnecessarily confusing to use import for non-importing tasks. It's usually done only as syntactic sugar, not because it actually needs to happen at that stage. It's not a huge problem, but I appreciate the fact that modules like Test::More let's me use a more traditional alternative syntax.

Re:abuse of import

jonswar on 2007-09-05T10:18:25

What about pragmas, like strict?

use strict qw(refs);

Would you prefer

use strict; BEGIN { strict->enable(qw(refs)) }

Imports seem like a general way to parameterize the use of a module. The historical choice of the name import() shouldn't necessarily be taken as a permanent restriction on usage.

Re:abuse of import

perrin on 2007-09-05T13:54:06

As an actual pragma, strict is kind of a special case. It also has an actual need to get the information at compile time, unlike many uses of import which would work fine with a standard sub call. I'd still prefer it if strict didn't look it was about to create a sub called "refs", but it's kind of too late now.

Re:abuse of import

bart on 2007-09-05T19:48:22

I like the idea of generating the accessors at compile time. In that regard, is is a lot like importing.

Re:abuse of import

ysth on 2008-01-07T02:15:57

Well, since strict "refs" is lexically scoped, there is no BEGIN { } equivalent possible (see the block there?). Perhaps use constant is a better example.

Re:abuse of import

dagolden on 2007-09-04T19:47:03

To be clear, the abuse in import is the @ISA manipulation.

Otherwise, the import is passed a list of methods and Object::Tiny creates them in the caller's namespace. That they happen to be created on the fly instead of mapped to subroutines defined in Object::Tiny doesn't really matter, in my opinion.

Re:abuse of import

Alias on 2007-09-05T00:47:07

base.pm manipulates @ISA in it's import method...

POD

miyagawa on 2007-09-04T18:08:46

You might want to move the POD document to a separate .pod file or inline them before __END__, so it doesn't increase the memory usage.

The document is a few kilobytes but apparently that would be a bit siginificant for your ::Tiny module if you want to claim the small memory footprint :)

Re:POD

miyagawa on 2007-09-04T20:36:47

Well, scratch this silly comment :) I remember I've heard that Perl allows a run-time access to the POD document tree in some of the past YAPCs but cant find the reference to it anymore. I guess it doesn't matter as long as you use __END__. I might be wrong again :)

Re:POD

Alias on 2007-09-05T00:48:03

It's probably a good idea anyway, it might save reading an extra block from the filesystem :)

Spelling/etc mistakes

Alias on 2007-09-05T00:55:36

I should comment for anyone reading this on the use.perl.org front page that I tend not to proof journal entries, because I don't expect them to end up on the front page :)

There's a cleaned up revised version in my actual journal page.

accessors.pm

srezic on 2007-09-05T08:06:36

Can you make a similar comparison between Object::Tiny and accessors.pm? At least this module uses the same syntax as Object::Tiny, declaring accessors in the "use" line.

Sure

Alias on 2007-09-05T15:45:37

Will do, stay tuned.

Hmm...

siracusa on 2007-09-08T00:15:28

Object.pm in Rose::Object has fewer lines of code and does even less! It's no Object::Really::Tiny, though ;)

Class::Accessor::Classy

Eric Wilhelm on 2007-09-09T06:15:13

1. You can subclass it -- subclass := customize.

2. It is ridiculously fast.

3. The new() method is optional (think multiple inheritance.)

4. Immutable (set-once) mutator support.

5. Terse, declarative syntax.

6. It doesn't want to be your subclass.

7. Zero namespace pollution.

8. Properly named setters.

9. Supports truly private methods.

10. Class accessors, constants, etc.

    package My::Class;
    use Class::Accessor::Classy;
    with 'new';
    ro qw(foo bar);
    rs baz => \ (my $set_baz);
    rw qw(bop boop bip);
    ri qw(this that);
    ro_c suitcase => 'red';
    constant seven => 7;
    constant eight => this->seven + 1;
    no Class::Accessor::Classy;

I designed it to be usable in a large system with lots of inheritance (dotReader) and it is rather battle-hardened at this point.

No, it is not as fast as Object::Tiny, but it is faster and does more than Class::Accessor::Fast.

http://scratchcomputing.com/tmp/object_tiny_benchmark.pl