in reply to Re: Re: $class = ref $class || $class
in thread Constructor/Factory Orthodoxy

Howdy!

Why? Re: Re5: Constructor/Factory Orthodoxy by steves spoke to this.

For myself, if I have a bunch of classes that inherit from a base class that provides the constructor (or at least a default constructor), and I want "another one of these", where I don't necessarily know exactly what package "this" is blessed in to, I either have to do ref($this) everywhere I do this, or just expect that $this can(new) and let new figure it out.

Sure, if I call $obj->new, Perl may have to dredge through @INC@ISA to find the method, where Class->new is explicit, but that may force me (the lazy programmer) to have to discern Class from $obj every time. If I bury that discovery in new, I only have to do it in one place.

I'm not clear on what you mean by "more complicated and slower". Well, I can see the "slower" part, but "more complicated"?

yours,
Michael

Update: corrected erroneous reference to @INC (where I should have said @ISA) (slaps forehead)

  • Comment on Re: Re: Re: $class = ref $class || $class

Replies are listed 'Best First'.
Re: $class = ref $class || $class
by Abigail-II (Bishop) on Feb 28, 2003 at 13:24 UTC
    @INC is only consulted when doing a use or require. It's not consulted for object or method calls.

    Don't expect there to be much difference in speed between $obj -> new and Class -> new. The overhead of calling the method dwarves any finding of the class.

    Abigail

(Re:) $class = ref $class || $class
by rir (Vicar) on Feb 28, 2003 at 15:52 UTC
    Most of the code I've seen with this construct in new does not have the usage you describe as a justification. And I don't find your justification compelling where it does apply.

    I would prefer to write (ref $obj)->new instead of $obj->new because that tells the reader that the type of $obj is variable or questionable. If I write Obj->new there is no doubt of the type. There is less chance the reader will research the wrong package if he wants to do something with the created object.
    If I just write $obj->new as a convenient shorthand I hide this info. Thus I make the code more complicated to understand.

      Howdy!

      I don't see a compelling argument either way.

      Assuming the situation I posit holds, the reader or user will, of necessity, have consulted the documentation for the modules that would, of course, speak to matters relevant to "what can I do with this thingy". It pretty much follows from the posited situation that the possible values of ref($obj) are closely related in some useful manner, so as to permit generalization. Heck, they may all have an identical set of methods, differing only in how those methods do stuff.

      If I am in a situation where I need "another ref($obj)", I, in my laziness, don't want to be forced to say ref($obj) just for the sake of truth and beauty. I do not see that having "new" take the ref() if necessary as being, per se, a Bad Thing.

      Perhaps we will have to agree to disagree.

      yours,
      Michael

        In your argument there is a lot of assumed knowledge about the code. I hope you have great recall or don't need to maintain your code in a distant future.

        In the below code $response->finish is not working correctly. It seems someone forgot to add code to register some action with the legacy system to the called finish method. Some client has expanded his use of the info generated and this is suddenly a noticed misfeature. As the newly hired Perl expert your assigned task is to fix the problem.

        # Mark the calling request object as answered, use the # ID param to create and return an response packet object. # Let the old system know this is done. sub _respond { my ($self, $request, $id, $response ) = @_; my $response = $request->new; ### Hey!! $request->count( $request->count + 1 ); if ( $response->approved) { $response->requestor( $id); $response->finish( SUCCESS ); $request->answered( $id) Request_handler->reap( $request->id()); return $response; } $response->finish( FAIL); return; }
        There are 27 variations of the type Packet floating around the system. _respond is called from 19 different places all but 2 of which get $request or its forerunner passed in.

        My point: Do your posited circumstances exist here?

        The author who wrote the code knew. He knew that $_[1] would always be a Packet_Foreign here. He didn't care about truth or clarity so the find part of a find and fix problem now requires much more effort.

        I am not a great typist so I like to avoid unnecessary typing but sacrificing information for the sake of fewer keystrokes is foolish.