git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Jaeger <christian@jaeger.mine.nu>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Petr Baudis <pasky@suse.cz>
Subject: Re: [PATCH] Git.pm: do not break inheritance
Date: Sun, 19 Oct 2008 00:21:06 +0200	[thread overview]
Message-ID: <48FA6152.6020006@jaeger.mine.nu> (raw)
In-Reply-To: <7vabd1aaqx.fsf@gitster.siamese.dyndns.org>

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.

      reply	other threads:[~2008-10-18 22:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-18 18:25 [PATCH] Git.pm: do not break inheritance Christian Jaeger
2008-10-18 20:50 ` Junio C Hamano
2008-10-18 22:21   ` Christian Jaeger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48FA6152.6020006@jaeger.mine.nu \
    --to=christian@jaeger.mine.nu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pasky@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).