Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
There's more than one way to do things
 
PerlMonks  

Re (tilly) 1: Nested Classes

by tilly (Archbishop)
on Mar 02, 2001 at 20:33 UTC ( #61814=note: print w/ replies, xml ) Need Help??


in reply to Nested Classes

There is probably a better way to do this. (Likely on CPAN.) Plus this is slow. But here is a very simple implementation of a different inheritance scheme than the one that Perl uses. This is based on each object being its own class. Call the def method to add new methods to the object. Call new to generate an object that inherits from the parent. Call "call" to call methods you have inherited, or just call them directly. There is a basic search mechanism. Multiple inheritance is not supported. Methods follow the usual Perl semantics. (The first argument is the object, the rest are arguments to the method.)

package ObjectClass; use Carp; use strict; use vars qw($AUTOLOAD); sub call { my $self = shift; my $meth = $self->find_meth(shift); $meth->(@_); } sub def { my $self = shift; { my $meth = shift; my $implement = shift; $self->{meth_cache}->{$meth} = $implement; redo if @_; } } sub find_meth { my $self = shift; my $meth = shift; my $cache = $self->{meth_cache}; if (exists $cache->{$meth}) { return $cache->{$meth}; } elsif (exists $self->{proto}) { return $self->{proto}->find_meth($meth); } else { confess ("Object does not implement method '$meth'"); } } sub new { my $proto = shift; # Note for Merlyn, this time it is not cargo-cult programming! :-P unless (ref($proto)) { my $class = $proto; $proto = { meth_cache => {}, }; bless($proto, $class); } my $self = { meth_cache => {}, proto => $proto }; bless $self, ref($proto); } sub AUTOLOAD { my $self = shift; $AUTOLOAD =~ s/.*:://; return if $AUTOLOAD eq "DESTROY"; $self->call($AUTOLOAD, @_); } package main; # A simple test my $parent = new ObjectClass; $parent->def("hello", sub {print "Hello world\n"}); my $child = $parent->new(); $child->def("goodbye", sub {print "Goodbye\n"}); $parent->hello(); # Calling the defining object $child->hello(); # Inherit the method $child->goodbye(); # Method in the subclass $parent->goodbye(); # Blows up.
Does this make your mock classes easier to implement?

UPDATE
I did this mostly because I thought it would be fun to write. If you want to use this idea, I would suggest looking at Class::Classless or Class::SelfMethods.


Comment on Re (tilly) 1: Nested Classes
Download Code
Re: Re (tilly) 1: Nested Classes
by dcorbin (Sexton) on Mar 06, 2001 at 22:09 UTC
    Thanks. I think that the might achieve what I was after. Since there was some confusion about what I really want to do, and why, I'll try to give you an example, but I'm going to have to show it in pseudo-java.
    public class Foo { public void doSomething(Bar bar) { ... } }
    now, I want to write code that tests Foo.doSomething. I want that test to be independent of any problems that Bar might have. So, I write this...
    public class FooTest { testDoSomething() { class MockBar extends Bar { // code to simulate a "Bar" } ... bar = new MockBar(); foo = new Foo(); foo.doSomething(bar); // check that the right things happened to bar } }
      Before going further, you might want to give Test::Unit a shot and see if it will work for you.
        Test::Unit is simply a framework. It doesn't change HOW you write the actual code that does the testing. But thanks for the pointer.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://61814]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (10)
As of 2014-04-21 16:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (497 votes), past polls