Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^3: Invoking bless triggers "Can't resolve method ..." error

by AnomalousMonk (Archbishop)
on Jul 08, 2015 at 22:10 UTC ( [id://1133827]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Invoking bless triggers "Can't resolve method ..." error
in thread Invoking bless triggers "Can't resolve method ..." error

I replaced the name of the parent class with <module-name>. […] The variable $class contains the name of the current package ...

I assume that <module-name> is a valid class name. The quoted statements suggest to me that the class <module-name> and the "current package", i.e., class, are not the same. IOW, you are creating an object of class <module-name> and then severing the connection of object data to that class by re-bless-ing the object into a class which has an unknown (to me, at least) relationship to the generating class. This seems to me to be a very good recipe for major Brain Hurt.

Is there any reason not to use the "standard" instantiation process, i.e., use the new constructor of the parent/base/super class, then add data, etc., to the object appropriate to the child/derived/sub class before returning the object reference?


Give a man a fish:  <%-(-(-(-<

Replies are listed 'Best First'.
Re^4: Invoking bless triggers "Can't resolve method ..." error
by turkanis (Novice) on Jul 09, 2015 at 05:33 UTC

    I am using the standard instantiation process: creating an instance of the parent class and reblessing it as an instance of the subclass. The two classes are related by ISA. If I didn't do this, methods overridden by the subclass would not be invoked and new methods defined by the subclass would not be resolved.

      I am using the standard instantiation process: creating an instance of the parent class and reblessing it as an instance of the subclass.

      That sounds quite broken. Perl classes usually have a constructor that takes the class name from the caller, not the package name, and blesses a reference into that class. No reblessing needed:

      #!/usr/bin/perl use strict; use warnings; { package DemoA; sub new { my $class=shift; my $self=bless {},$class; return $self; } sub hello { my $self=shift; print $self->message(),"\n"; } sub message { my $self=shift; return 'Hello World'; } }; { package DemoB; use parent -norequire => 'DemoA'; sub message { my $self=shift; return 'Shalom'; } }; my $obja=DemoA->new(); $obja->hello(); # writes "Hello World" my $objb=DemoB->new(); $objb->hello(); # writes "Shalom"

      It is possible to use a modified constructor, using the SUPER notation:

      sub new { my $class=shift; my $self=$class->SUPER::new(@_); $self->{'x'}='y'; return $self; }

      Still, no reblessing needed.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        I think what the OP really wants is what pattern afficionados call a "Factory Method". That factory method shouldn't (re)bless at all but dispatch to the appropriate constructor:

        package FooParent; use Carp 'croak'; sub new { # Return either a FooSpecial1 or FooSpecial2 my( $class, %options )= @_; if( $options{ special } == 1 ) { return FooSpecial1->new( %options, special1_param => 'somethin +g' ); } elsif( $options{ special } == 2 ) { return FooSpecial2->new( %options, other_special_param => 'som +ething else' ); } else { croak "Unknown special '$options{special}' requested"; }; }; package FooSpecial1; package FooSpecial2; package main; my $frobnitz = FooParent->new();

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-18 18:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found