Re: [PATCH] Git.pm: do not break inheritance

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio C Hamano wrote:
That's how you would write class methods, isn't it?  IOW, your callers
can say:

	my $self = new Git();
        $self->method(qw(a b c));
        Git::method(qw(a b c))

and you can start your method like this:

	sub method {
        	my ($self, @args) = _maybe_self(@_)
                ...
	}

and use @args the same way for either form of the call in the
implementation.

I see, a magic way to offer both an OO and procedural api. Well, partial procedural api, since not all of the methods can work without the $self.

Two obvious pitfalls are:

 - You cannot use $self if you set up your parameters with _maybe_self;

 - The second form of the call would call directly into Git::method, never
   your subclasses implementation, even if you write:

	use Git;
        package CJGit;
        our @ISA = qw(Git);

        sub method {
        	...
	}


(This is no problem iff people are calling procedures in object notation if they actually have got an object at hands. I.e. if you've got some code which does:

my $repo= Git->repository(...);
$repo->foo;

then all is fine, and I would think it would be weird if people called Git::foo($repo, ... ) in such a case. Well for my purposes it's not a problem anyway, since if a user wants to use the extensions, he needs to actually do this:

my $repo= CJGit->repository(...);

and then it should be clear that one shouldn't call Git:: directly. The problem will only be in cases where an extended object is being fed to existing code which calls Git:: with objects in the hope that virtual method calls are going to the extended class; well, let's fix those bad call sites when they are being discovered... Maybe this warrants a warning somewhere.)

 sub _maybe_self {
-	# This breaks inheritance. Oh well.
-	ref $_[0] eq 'Git' ? @_ : (undef, @_);
+	UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
 }
# Check if the command id is something reasonable.

The patch looks Ok, as long as you have a working UNIVERSAL::isa() in your
version of Perl.  My reading of perl561delta,pod says that Perl 5.6.1 and
later should have a working implementation.

From http://perldoc.perl.org/perl561delta.html:

UNIVERSAL::isa()

A bug in the caching mechanism used by UNIVERSAL::isa() that affected base.pm has been fixed. The bug has existed since the 5.005 releases, but wasn't tickled by base.pm in those releases.

This looks like only a bug in some (corner?) cases; I've verified that I've been using the isa() method *or* function since perl 5.005_03, and haven't had issues with it. I can't easily verify though when I switched from

#if (Scalar::Util::blessed($value) and $value->isa("Eile::Html")) {
to
if (UNIVERSAL::isa($value,"Eile::Html")) {

(because it was simpler to write, once I discovered that I could just call the function directly instead of relying on method dispatch) but that might not have made a difference.

Christian.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux