Or even better,
$_[$index]->isa('SVN::Client')
This will break if $_[$index] is not a package or object reference, which is
exactly what this portion of the code appears to deal with. Best keep it the
other way ☺
From: Geoff Rowell [mailto:[email protected]]
Sent: Tuesday, September 27, 2011 2:14 PM
To: Thompson, Thomas J
Cc: [email protected]
Subject: Re: perl SVN::Client bug
On Sep 27, 2011, at 4:25 PM, "Thompson, Thomas J"
<[email protected]<mailto:[email protected]>> wrote:
Hi,
I’m an intermediate perl developer with lots to learn, but I think I’ve found
an issue with the perl subversion bindings that I’d like to pass by you folks
to ensure it’s not just operator error. I would give you the version I’m
working with, but I see no VERSION variable in the SVN::Client module. What
version information would be useful?
I tried to subclass SVN::Client, but I found that function calls were failing
with type errors. I brought this up in this thread on perlmonks:
http://www.perlmonks.org/?node_id=928123
I was seeing errors that look like this:
TypeError in method 'svn_client_ls', argument 2 of type 'char const *'
I found out this section of code handles arguments for calls to the svn
functions:
# import methods into our name space and wrap them in a closure
# to support method calling style $ctx->log()
foreach my $function (@_all_fns)
{
no strict 'refs';
my $real_function = \&{"SVN::_Client::svn_client_$function"};
*{"SVN::Client::$function"} = sub
{
my ($self, $ctx);
my @args;
# Don't shift the first param if it isn't a SVN::Client
# object. This lets the old style interface still work.
# And is useful for functions like url_from_path which
# don't take a ctx param, but might be called in method
# invocation style or as a normal function.
for (my $index = $[; $index <= $#_; $index++)
{
if (ref($_[$index]) eq 'SVN::Client')
{
($self) = splice(@_,$index,1);
$ctx = $self->{'ctx'};
last;
} elsif (ref($_[$index]) eq '_p_svn_client_ctx_t') {
$self = undef;
($ctx) = splice(@_,$index,1);
last;
}
}
The problem here is this line:
if (ref($_[$index]) eq 'SVN::Client')
This breaks if you attempt to subclass SVN::Client to add functionality. The
result is type errors because the invocant is not removed from the function
arguments before being passed through to the svn api. This should instead be:
if (UNIVERSAL::isa($_[$index], 'SVN::Client')
What should I do from here to ensure it is addressed? I’d like to help out the
perl/svn community.
Or even better,
$_[$index]->isa('SVN::Client')
-Geoff