Dmitry Dmitry - 2 months ago 12
Perl Question

Perl: Can I associate a CODE reference with a HASH reference that contains it?

I want to create a hash reference with code references mapped to scalars(strings) as its' members.

So far I have a map reference that looks something like this:

my $object;
$object = {
'code1' => sub {
print $_[0];
},
'code2' => sub {
return 'Hello, World!';
},
'code3' => sub {
$object->{code1}->($object->{code2}->());
}
};
$object->{code3}->();


I would like to be able to "bless" 'code3' reference in $object with $object so I can do something like:

my $object;
$object = {
'code1' => sub {
print $_[0];
},
'code2' => sub {
return 'Hello, World!';
},
'code3' => sub {
$self = shift;
$self->{code1}->($self->{code2}->());
}
};
$object->{code3}->();


however bless only works with packages, rather than hash tables.

Is there any way to do this in Perl 5 version 22?

Answer

You are doing sub calls (not method calls), so you simply forgot to pass $self as a parameter.

my $object = {
    code1 => sub {
        print $_[0];
    },
    code2 => sub {
        return 'Hello, World!';
    },
    code3 => sub {
        my $self = shift;
        $self->{code1}->( $self, $self->{code2}->($self) );
    }
}; 
$object->{code3}->($object);

But I think you're trying to create JavaScript-like objects. You can start with the following:

package PrototypeObject;

sub new {
   my $class = shift;
   my $Self = bless({}, $class);
   %$self = @_;
   return $self;
}

sub AUTOLOAD {
   my $self = shift;
   ( my $method = $AUTOLOAD ) =~ s/.*:://;
   return $self->{$method}->($self, @_);
}

1;

use PrototypeObject qw( );

my $object = PrototypeObject->new(
    code1 => sub {
        print $_[0];
    },
    code2 => sub {
        return 'Hello, World!';
    },
    code3 => sub {
        my $self = shift;
        $self->code1( $self->code2() );
    }
}; 

$object->code3();