Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Problem with Class::Accessor::Faster

by jmmitc06 (Sexton)
on Jul 30, 2013 at 01:30 UTC ( #1046936=perlquestion: print w/ replies, xml ) Need Help??
jmmitc06 has asked for the wisdom of the Perl Monks concerning the following question:

Perl Monks:

I have a problem changing from 'Class::Accessor::Fast' to 'Class::Accessor::Faster'. From what I understood, simply changing from Fast to Faster should have required no code modification; however, when a script invokes and tries to use this module I receive the error:

"Not an ARRAY reference at /usr/local/bin.../Class/Accessor/Faster.pm"

The code for the module:

#!/usr/bin/perl #Atom.pm #Contains the methods for Atom, an object that represents an atom with +in a compound. package Atom; use base 'Class::Accessor::Faster'; use strict; #use warnings; #The following hashes to allow for conversion of mol file charge code +to accepted numerical representations of charge and oxidation. my %SDF_charge_conversion = (2 => 2, 3 => 1, 4 => "Doublet Radical", 5 + => -1, 6 => -2, 7 => -3, 0 => 0); my %SDF_oxidation_modification = (2 => 2, 3 => 1, 4 => 1, 5 => 1, 6 => + 2, 7=> 3, 0 => 0); #Create prototypical atom object my @atom_fields = ( "element" => 0, #a string representing the element type +of the atom "SDF_charge" => 0, #an integer representing the SDF_charge +code of the atom "index" => 0, #an integer representing the index of th +e atom in the Atoms array of the molecule "bond_count" => 0, #an integer representing the number of b +onds that contain the atom "bond_order_count" => 0, #an integer representing the sum of all +bond orders of the bonds that contain the atom "oxidation_modifier" => 0, #an integer representing the oxidation s +tate of the atom (calculated from charge) "charge" => 0, #an integer representing the charge of t +he atom (calculated from charge) ); Atom->mk_accessors( grep { $_ ne "0"; } (@atom_fields)); #Name: new #Description: Creates a new 'atom' object #Options: None #Input: @_ - @(element, SDF_charge, index, bond_count, bond_order_coun +t, oxidation_modifier, charge) #Output: $self - Atom Object sub new { my $proto = shift @_; my $self = { @atom_fields, @_ }; $self = bless ($self, ref($proto) || $proto); $self->oxidation_modifier($SDF_oxidation_modification{$self->SDF_cha +rge}); $self->charge($SDF_charge_conversion{$self->SDF_charge}); return $self; } 1;

The only change I made was changing Fast to Faster to receive the error. I thought the differences were internal. If any one could help me figure out why I get this error and what modifications I need to make it work, I would greatly appreciate it. I can post the script that envokes the module if needed, but its large and I don't think it would help.

Comment on Problem with Class::Accessor::Faster
Download Code
Re: Problem with Class::Accessor::Faster
by zork42 (Monk) on Jul 30, 2013 at 04:25 UTC
    I have a problem changing from 'Class::Accessor::Fast' to 'Class::Accessor::Faster'. From what I understood, simply changing from Fast to Faster should have required no code modification; however, when a script invokes and tries to use this module I receive the error:
    There must be some other differences otherwise there would be no point in having both Class::Accessor::Fast and Class::Accessor::Faster.
    If they were identical apart from speed, then Marty Pauley (the author of both modules) would have just sped up Class::Accessor::Fast, and would not have created Class::Accessor::Faster.

    Their documentation has these brief summaries, with more details in their descriptions. I'd check there :)
    • "Class::Accessor::Fast - Faster, but less expandable, accessors"
    • "Class::Accessor::Faster - Even faster, but less expandable, accessors"
Re: Problem with Class::Accessor::Faster
by kcott (Abbot) on Jul 30, 2013 at 06:20 UTC

    G'day jmmitc06,

    The documentation for Class::Accessor::Faster only contains five short sentences in its DESCRIPTION. The fourth one says:

    "Class::Accessor::Faster uses an array reference underneath to be faster."

    Class::Accessor::Faster's source code has this constructor code:

    sub new { my($proto, $fields) = @_; my($class) = ref $proto || $proto; my $self = bless [], $class; ...

    You subclass Class::Accessor::Faster with Atom which has this constructor code:

    sub new { my $proto = shift @_; my $self = { @atom_fields, @_ }; $self = bless ($self, ref($proto) || $proto); ...

    This is almost certainly the cause of the error.

    Class::Accessor::Fast subclasses Class::Accessor (see Class::Accessor::Fast's source code). Class::Accessor's source code has this constructor code:

    sub new { my($proto, $fields) = @_; my($class) = ref $proto || $proto; $fields = {} unless defined $fields; # make a copy of $fields. bless {%$fields}, $class; }

    So, if you wish to subclass Class::Accessor::Fast, you'll need a hashref-based object (which presumably worked for you initially); however, to subclass Class::Accessor::Faster, you'll need a arrayref-based object.

    -- Ken

Re: Problem with Class::Accessor::Faster
by tobyink (Abbot) on Jul 30, 2013 at 06:54 UTC

    As others have said, Class::Accessor::Faster uses an arrayref-based object, not hashref-based.

    Moo is faster than Class::Accessor::Fast and Class::Accessor::Faster, but with my patch Class::Accessor::Fast can rival Moo's speed.

    However, if Moo detects that Class::XSAccessor is installed, it's able to use that to accelerate itself still further, and blows both Class::Accessor::Fast and Class::Accessor::Faster out of the water.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

        Like this!

        package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Problem with Class::Accessor::Faster
by jmmitc06 (Sexton) on Jul 31, 2013 at 02:51 UTC
    Thanks for the replies, I misinterpreted the fact that faster used arrayrefs internally instead of hashrefs to mean that on the exterior the modules would act the same. Thanks for the clarifications, unfortunately though I think that the time I will save by switching would be offset by the time it would take to rewrite the modules. In the future though, I think I will switch to faster.

    I will apply the patch mentioned as well, thanks for that.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1046936]
Approved by Loops
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2014-10-02 02:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (45 votes), past polls