My goal is to be able to use $obj like this:
print $obj->hello() . $obj->{foo};
And I would like to create an object inline, maybe using something like this:
my $obj = (
foo => 1,
hello => sub { return 'world' }
);
but when I try to use $obj as an object, I get an error saying that $obj has not been blessed. Is there some base class (like stdClass in PHP) I can use to bless the hash so that I can use it as an object?
For those that know JavaScript, I am trying to do the following, but in Perl:
# JS CODE BELOW
var obj = { foo: 1, hello: function () { return 'world' } };
echo obj.hello() + obj.foo;
Perl would require a little help to do this. Because it doesn’t consider code references stored in hashes as “methods”. Methods are implemented as entries into a package symbol table. Perl is more class-oriented than JavaScript, which proudly proclaims that it is more object-oriented (on individual objects).
In order to do that functionality, you would have to create a class that mapped references in this way. The way to get around methods in the symbol table is the
AUTOLOADmethod. If a package contains anAUTOLOADsubroutine, when a call is made to a blessed object that Perl cannot find in the inheritance chain, it will callAUTOLOADand set the package-scoped (our) variable$AUTOLOADwill contain the full name of the function.We get the name of the method called, by getting the last node (after the last ‘::’) of the fully-qualified sub name. We look to see if there is a coderef at that location, and if there is, we can return it.
Then you would bless the object into that class:
Normally, in an
AUTOLOADsub I “cement” behavior. That is, I create entries into the package symbol table to avoidAUTOLOADthe next time. But that’s usually for a reasonably defined class behavior.I also designed a
QuickClasswhich creates a package for each object declared, but that contains a lot of symbol table wrangling that now days is probably better done withClass::MOP.Given the suggestion by Eric Strom, you could add the following code into the AutoObject package. The
importsub would be called anytime somebodyuse-dAutoObject(with the parameter'object').And then, when you wanted to create an “object literal”, you could just do:
And the expression would be:
You could even do:
And you have an “object literal” expression. Perhaps the module would be better called
Object::Literal.