cramdorgi has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I try to fix a problem in a CPAN module: ClearCase::Argv.
This module should share a co-process running a cleartool executable, to service requests. At least in so-called ipc mode. But in my understanding, it doesn't.

ClearCase::Argv is a specialization of Argv.
My tentative changes involve adding a constructor, where there was none: the base constructor was enough—I assume.

So, here are my changes (I introduce a reference count of the objects using the same co-process. Using the same process may mean using the one set up at class level in the ipc member function, or the one used in an existing object, if performing a copy-construction. The DESTROY member also calls ipc but with a 0 argument, thus resulting in a decrement, and optional cleanup):

ClearCase-Argv> ct diff -diff -pred Argv.pm 18c18 < --- > my %pidcount; 425d424 < # Send an explicit "exit" command and close up shop. 426a426 > return 0 if --$pidcount{$self->{IPC}->{PID}}; 426a427 > # Send an explicit "exit" command and close up shop. 440c441,444 < --- > if (($self ne $class) and $class->{IPC}) { > ++$ipccount{$class->{IPC}}; > return 0; > } 616a621,634 > > # Constructor, and copy constructor as clone, with $proto > sub new { > my $proto = shift; > my $self = $proto->SUPER::new(@_); > if (ref($proto)) { > # Correct the effect of the base cloning on globs > my $down = $proto->{IPC}->{DOWN}; > $self->{IPC}->{DOWN} = $down; > my $back = $proto->{IPC}->{BACK}; > $self->{IPC}->{BACK} = $back; > ++$ipccount{$proto->{IPC}}; > } > }
When running make test, I get now:
... Can't call method "qx" without a package or object reference at test.p +l line 50.
Line 50 in test.pl is:
49: my $wdv = ClearCase::Argv->new("pwv -wdview -s"); 50: my $view = $wdv->qx;
...the first use of an object created with my new constructor... Note that this construction involved arguments.
So, I guess my construction went badly wrong.
I can anticipate an other problem: new in the base class is aliased to clone. I should probably reproduce this in the derived class. Anyway, I assume this is not the cause of the current error.

Any clue what's so wrong with my construction?
Thanks,
Marc

Replies are listed 'Best First'.
Re: Constructor in derived class
by FunkyMonk (Bishop) on Mar 30, 2008 at 23:06 UTC
    new needs to return a blessed reference: ie return $self

      Thanks!
      Dumb me.
      For my defense, may I claim that it occurred to me during my sleep? In any case, I very much appreciate your fast and effective answer!
      I added the two lines, and at least make test passed:
      bless $self, $proto; return $self;

      Do I need to add to the derived class a copy of the following, found in the base one:

      *clone = \&new;
      or may I trust that the calls to clone will be polymorphically translated to ClearCase::Argv::new (i.e. to calls to the derived class constructor)?
      Based on my C++ understanding, I add it for now, thinking that there is no way the base class might know which derived to construct...

      Are there users of ClearCase::Argv here, who can share my concerns and confirm symptoms I record? With whom I could share code before publishing it to CPAN (or in this case, sending it to the author for him to publish it)? What would be the best way to proceeed?

      Thanks!

      Marc

        I test my change and get an error:
        ClearCase-Argv> perl -Iblib/lib -Iblib/arch -e 'use ClearCase::Argv;su +b p{$a=shift;print"--${a}--\n";system(qw(pgrep cleartool))}sub v{$c=s +hift;$c->argv(q(pwv))->system}ClearCase::Argv->ipc(1);p(1);$c1=ClearC +ase::Argv->new;p(2);$c2=ClearCase::Argv->new;v($c1);p(3);$c1->clone-> +argv(q(pwv));p(4);v($c1);p(5);v($c1);' --1-- 22003 --2-- 22003 Working directory view: emagiro Set view: emagiro --3-- 22003 Attempt to bless into a reference at blib/lib/ClearCase/Argv.pm line 6 +37, <GEN1> line 3.
        This is the line:
        bless $self, $proto;
        I assume it is wrong to bless the reference I got in the case this was used as a copy constructor.
        So, I must test it?
        bless $self, ref($proto) ? ref($proto) : $proto;
        This makes my test happy...

        Marc