With inside-out classes it can be arranged that the class itself behaves like an object, which I'll call its generic object. The generic object can be initialized and normal accessors can be used with it to set and retrieve values. It is, however, not a real object in the sense of a blessed reference. Different classes have (represent? are?) different generic objects.

What it amounts to is that every object method of such a class can also be used as a class method. Here is a minimal class that shows how to enable this feature.

The modification is in the function id() used to get the reference address of an object when accessing data.
package SomeClass; use Scalar::Util; # The traditional id() function is modified: for a non-ref, return # the argument, not undef sub id { Scalar::Util::refaddr( $_[ 0]) || shift } { # a field (attribute, object variable) with a read/write accessor my %some_field; sub some_field { my $obj = shift; $some_field{ id( $obj)} = shift if @_; $some_field{ id( $obj)}; } sub init { my $obj = shift; $some_field{ id( $obj)} = shift; $obj; } sub new { my $class = shift; bless( do{ \ my $o})->init( @_); } } package main; my $obj = SomeClass->new( 123); print $obj->some_field, "\n"; SomeClass->init( 456); print SomeClass->some_field, "\n";
This works, of course, because with this id() function the values of some_field for the generic object are stored in the same hash as the values for real objects, but keyed by the class name. Since the keys of real objects are integers in decimal, there is no conflict.

With an un-modified id() function all such accesses would be keyed by the empty string, independent of the class (probably spewing warnings). It might appear to "work", but would break down with subclassing.

There are probably not too many uses for the generic object, but two come to mind. For one, often a place is wanted to store default values for all objects. The generic object offers itself as a class-wide template to hold such values.

Another use would be in the implementation of singleton classes. Defining

sub new { my $class = shift; $class->init( @_); }
would make sure that no real object (blessed ref) is created. Only the generic object (the invioking class) is ever returned by new().

I could contrive ther uses, but I'll stop here. I feel the feature has a certain neat-appeal, applications are secondary :)

Anno


In reply to Generic object in inside-out classes by Anno

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.