On Wed, Jun 27, 2001 at 01:00:40PM -0700, David Whipp wrote:
> For the distinction between methods vs members, I don't think
> we have to stray too far from perl-is-perl. Afterall, we already
> know that &foo is a function and $foo is a scalar. So from an
> implementation perspective there's no problem giving methods
> and members a separate namespace. Its just a syntax issue ;-).
> 
> We already have a "sub" keyword; and one of its parameters is
> the name of the function. Allow that paramter to be a hard
> reference to an object, and you've got a way of defining
> object-level functions (members are objects):
> 
>   sub $foo.{bar} { ... }  #? === sub $foo.bar { ... } ?
> 
> To read the function associated, you can use a property "sub":
> 
>   $foo.{bar}.sub # returns the subroutine.
> 
> calling a property can pass a value, and parentheses are optional:
> 
>   $foo.{bar}.sub { ... } # context says {} is subroutine composer
> 
> So the correspondance, "foo $bar" === "$bar.foo", is maintained.
> 
> Now I just need to work out the meaning of "sub $foo {}".

I can do you one better.  I can make this even more elegant and I can
make it work in Perl 5 and work just as fast as normal objects.

Observe.  Nothing up my sleeve...

    package Class::Object;
    our $counter = 0;

    sub new {
        my($proto) = shift;
        my($class) = ref $proto || $proto;

        my $obj_class;
        if( ref $proto ) {
            $obj_class = ref $proto;
        }
        else {
            $obj_class = $class.'::'.$counter++;
            @{$obj_class.'::ISA'} = $class;
        }
        bless {}, $obj_class;
    }

    sub sub {
        my($self, $name, $meth) = @_;
        *{ref($self).'::'.$name} = $meth;
    }


    package main;

    # Generate an object, give it a method called 'foo'
    my $obj = Class::Object->new;
    $obj->sub('foo', sub { return "FOO, I SAY!\n" });

    # Generate another object, give it a different method called 'foo'.
    my $another_obj = Class::Object->new;
    $another_obj->sub('foo', sub { return "UNFOO!\n" });

    # Get copies of those methods back out, just like any other.
    my $obj_foo = $obj->can('foo');
    my $another_foo = $another_obj->can('foo');

    # Same names, same classes, different methods!
    print $obj->foo;
    print &$obj_foo;
    print $another_obj->foo;
    print &$another_foo;

    print "Yep\n" if $obj->isa('Class::Object');
    print "Yep\n" if $another_obj->isa('Class::Object');

    # $obj->new clones itself, so $same_obj->foo comes out as $obj->foo
    my $same_obj = $obj->new;
    print $same_obj->foo;


That's basically what you want, right?


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>    http://www.pobox.com/~schwern/
Perl6 Quality Assurance     <[EMAIL PROTECTED]>       Kwalitee Is Job One
Death follows me like a wee followey thing.
        -- Quakeman

Reply via email to