Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re: SVN::Client subclassing issue

by tj_thompson (Monk)
on Sep 27, 2011 at 19:33 UTC ( #928157=note: print w/replies, xml ) Need Help??

in reply to SVN::Client subclassing issue

Ok, after some digging I believe I understand the issue. In the file as it creates functions there is a section of code that adjusts the call parameters. Specifically, it checks if the first function is blessed into 'SVN::Client'. If it is, the arguments are handled in one manner. If it is not, they are handled a different way.

# 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; } }

This seems to mean I can't directly subclass SVN::Client as at least some of the functions break. However, I have found a couple obscure mentions of subclassing SVN::Client in my I find that strange.

Guess I look for another way unless I want to modify I don't :)

Replies are listed 'Best First'.
Re^2: SVN::Client subclassing issue
by Anonymous Monk on Sep 27, 2011 at 19:42 UTC

    Guess I look for another way unless I want to modify I don't :)

    Make your class has-a-SVN::Client not is-a-SVN::Client?

    It seems to me that portion of SVN::Client is broken, in that it needs to use

    UNIVERSAL::isa($_[$index], 'SVN::Client')
    instead of ref/eq

    Apparently you can report bugs at

      Make your class has-a-SVN::Client not is-a-SVN::Client?

      This is what I had in mind. I was going to subclass initially because I wanted some functions to 'fall through' to the SVN::Client class without having to wrap each one. This should be easy enough to do from another object, but it's not something I've done before.

      So assuming my new Foo class is called with a function that is not part of the package, let's say Foo->cat. Foo does not have a cat function, but Foo does have a SVN::Client object. I'd like to pass a call to a function that does not exist in the current package to be handled by the SVN::Client object. What is the proper/elegant way to do this?

        our $AUTOLOAD; sub AUTOLOAD { my( $self )= shift @_; my( $class, $method )= $AUTOLOAD =~ /^(.+)(?:'|::)(.+)$/ or die "Invalid method name: $AUTOLOAD"; return if 'DESTROY' eq $method; die "Can't call internal method, $method, via ", __PACKAGE__, $/ if $method =~ /^_/; return $self->{whatever}->$method( @_ ); }

        Not so much "proper" or "elegant" but a thrown-together example but also not "improper" nor particularly "inelegant".

        - tye        

        See AUTOLOAD section of Modern Perl: the free book, and mind the caveats

        Assuming hashref has-a 'SVN::Client'

        sub AUTOLOAD { my ($name) = our $AUTOLOAD =~ /::(\w+)$/; my $method = sub { my $self = shift; return $self->{'SVN::Client'}->$name( @_ ); } no strict 'refs'; *{ $AUTOLOAD } = $method; return $method->( @_ ); }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://928157]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2018-07-17 12:07 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (363 votes). Check out past polls.