Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: RFR: Inside-out classes - a Class::InsideOut primer

by xdg (Monsignor)
on Mar 16, 2007 at 13:04 UTC ( [id://605148]=note: print w/replies, xml ) Need Help??


in reply to RFR: Inside-out classes - a Class::InsideOut primer

++ Very nice start to a tutorial -- and on a topic that continues to need it, as recent criticism suggests.

I have a few corrections and comments.

sub new { my $self = shift; register( $self );

It should be:

sub new { my $class = shift; my $self = register( $class );

That's the longhand approach for clarity of what the arguments mean. my $self = register( shift ) would be shorthand.

When provided with a single, non-reference argument, register treats it as a class name and will return a reference to an anonymous scalar blessed into the given class. Thus, considering this question:

$manager->{phone} = '555-1313'; # {{what is the behavior of this??}}

If you use the new() example I give above, this will die with an error as $manager is a reference to a scalar, not a hash.

Note that if you use an anonymous hash reference (using an alternate style of register):

sub new { my $class = shift; my $self = register( {}, $class ); # register does the bless, too

Then $manager->{phone} = '555-1313' will work as usual, but will have nothing to do with the value retrieved by $manager->phone().

Aren't inside-out objects fun?

public birthday => my %birthday, { set_hook =>; \&_set_birthday };

Extra semicolon. set_hook => \&_set_birthday

Return values from get_hook are ignored; the accessor expects that get_hook will simply modify '$_'.

This is incorrect. The behavior isn't symmetric with set_hook. For get_hook, $_ is a copy of the attribute -- you can modify it without affecting what is stored. The return value of the get_hook is returned from the accessor. Your example just happens to work because the last thing you do is $_ = strftime and that is what gets returned. You could also have done this:

sub _get_birthday { strftime '%m/%d/%Y', localtime( $_ ); # but NOT just localtime() }

But again, your tutorial has a nice build-up from simple to more advanced concepts, around a well-defined example (date storage). With some editing and clarifications from feedback here and elsewhere in the thread, it will probably be something I'm happy to either link to in the Class::InsideOut documentation or possibly even add as Class::InsideOut::Tutorial.

One thing you might want to clarify a bit more is the id() function and its importance in generating the unique ID for a object.

I also wouldn't describe Class::Std as "deprecated" -- I'm not a big fan, but it's certainly in use. It is very good for dealing with complex class hierarchies (as one would expect of a module by TheDamian) but I think it errs by not being more fundamentally robust.

My YAPC::NA 2006 presentation is another potential reference you could add.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Replies are listed 'Best First'.
Re^2: RFR: Inside-out classes - a Class::InsideOut primer
by radiantmatrix (Parson) on Mar 16, 2007 at 14:53 UTC

    Hm, some very good points. First off, thanks for pointing out the stray semi-colon -- it's an artifact from cleaning up the original HTML (there used to be an > there). Second, thanks for the clarification on get_hook, I must have simply mis-read the documentation: my bad.

    I'm of two minds about including the longer form of register... on the one hand, it would be more accurate, on the other, it does seem a little more confusing. It's clear that what I've got is probably inadequate, but I will have to give some thought to how much of that behavior I want to explain. That, and how best to convey it.

    As for the importance of the id function, would you care to expand? I'm certainly not an expert on inside-out objects, and I've just been using it as a bit of a mantra -- when I need the ID of an object, I do it this way -- I'd appreciate more insight into why I'm doing it. I can then distill that insight down (hopefully) into primer-appropriate materials.

    I call Class::Std "deprecated" on the basis that I would discourage its use to anyone who didn't really know what they were doing. I hadn't considered that others would take "deprecated" in different contexts; I will have to think about how to rephrase that.

    Thanks for the link to your presentation, I will look it over and consider it for mention.

    <radiant.matrix>
    Ramblings and references
    The Code that can be seen is not the true Code
    I haven't found a problem yet that can't be solved by a well-placed trebuchet
      As for the importance of the id function, would you care to expand? ... I'd appreciate more insight into why I'm doing it

      The real answer: Class::InsideOut expects/requires that the unique key for each object be its memory address (to ensure safety for threading and pseudoforks), so it provides the alias id() to Scalar::Util::refaddr.

      To explain it in the primer, it may be sufficient to say that each object needs to have a unique key and Class::InsideOut requires the use of the id() function to generate that unique key.

      Regarding Class::Std:

      I would discourage its use to anyone who didn't really know what they were doing.

      I think this is almost exactly what you should say in place of "deprecated".

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        The real answer: Class::InsideOut expects/requires that the unique key for each object be its memory address (to ensure safety for threading and pseudoforks), so it provides the alias id() to Scalar::Util::refaddr.

        I don't have a win32 perl available to test this right now, but doesn't a fork() in win32 perl change the refaddr? If so, does anyone know if Class::InsideOut handles that correctly?

Re^2: RFR: Inside-out classes - a Class::InsideOut primer
by j3 (Friar) on Mar 16, 2007 at 21:14 UTC
    With some editing and clarifications from feedback here and elsewhere in the thread, it will probably be something I'm happy to either link to in the Class::InsideOut documentation or possibly even add as Class::InsideOut::Tutorial.

    In Class::InsideOut::Manual::About, it says,

    All other implementation details, including constructors, initializers and class inheritance management are left to the user

    This suggests to me that maybe a Class::InsideOut::Manual::BestPractices would be helpful. After all, most prospective users of C::IO are probably familiar with using classic hashref-based classes, and it's easy to just stick with what you know ... unless there's there's some easy-to-follow guidelines that say, ``Look, if you just need to write some simple classes with some inheritance, your best bet might be to use modules X, Y, Z, and do it like so.''.

    By the way, for double-word score, include some references to relevant chapters and sections in Damian's PBP (detailing where C::IO BP differ from PBP being the most important, IMO).

    IMO, a doc like that would make it a no-brainer to start off your InsideOut-OOP life with C::IO.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://605148]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-24 08:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found