[Prev][Next][Index][Thread]

Re: Need help with Class-Allocated Slots



As common as class-slots are (at least in the programming I have done), I
would still prefer a more direct and less cumbersome method.  I would
not be content having to use the method you suggest every time I need a
class slot.

> > Neel Krishnaswami <neelk@alum.mit.edu> wrote:
> > > 
> > > The big problems with this that is it's hard to know what to do if
> > > there is a specialized method shadowing the basic getter. [...]
> > 
> > There could (ought to) be a way to qualify the ambiguous reference
> > to make it clear which reference is being requested, "method foo" of
> > "slot foo". In the absence of an unambiguous reference the system
> > could simply flag it as an error.
> 
> I'm not so sure of this, actually. The unification of slot access and
> method dispatch is one of the most elegant features of Dylan, and I'd
> hate to see it break without a really good rationale. IMO, this is the
> sort of thing that should either be part of a full-fledged MOP or not
> present at all.
> 
> > In practice, conflicts like this are less of a problem than the lack of
> > having the feature in the first place.  Multiple Inheritance can cause
> > conflicts as well, but that doesn't mean it should not be implemented
> > (which is the approach Java took with MI).
> 
> In this case, I think that if you need to access class slots before
> there are instances, you should use a module variable, like:
> 
>   define variable *bar* = 9;
> 
>   define method bar(obj :: <foo>) => (value)
>     *bar*
>   end method;
> 
>   define method bar-setter(value, obj :: <foo>) => (value)
>     *bar* := value
>   end method;
> 
> Then if you need the bare "class slot", you can access the variable
> directly. If all this seems kind of grotty to you, then a little
> macrology can make all the dirt go away:
> 
>   define macro class-slot-definer
>     {define class-slot (?class:name, ?:name) as ?:expression}
>       => {define variable "*!*" ## ?name ## "*!*" = ?expression;
>           define method ?name (obj :: ?class) => (value)
>             "*!*" ## ?name ## "*!*"
>           end method;
>           define method ?name ## "-setter" (value, obj :: ?class) => (value)
>             "*!*" ## ?name ## "*!*" := value;
>           end method;
>           define method class-slot(class :: subclass(?class), gf == ?name)
>             "*!*" ## ?name ## "*!*"
>           end method;
>           define method class-slot-setter(value,
>                                           class :: subclass(?class),
>                                           gf == ?name) => (value)
>             "*!*" ## ?name ## "*!*" := value;
>           end method class-slot-setter;}
>   end macro;
> 
> Use it like this:
> 
>   define class <foo> (<object>)
>   end class <foo>;
>   
>   define class-slot(<foo>, bar) as 10;
>   
>   define method main(appname, #rest arguments)
>     local method test(heading, val-1, val-2)
>   	    format-out(heading);
>   	    format-out("\n");
>   	    format-out("    x.bar is %=\n", val-1);
>   	    format-out("    class-slot(<foo>, bar) is %=\n", val-2);
>   	  end method test;
>   
>     let x = make(<foo>);
>     test("define class-slot(<foo>, bar) as 10;",
>          x.bar, class-slot(<foo>, bar));
>   
>     x.bar := 15;
>     test("x.bar := 15;", 
>          x.bar, class-slot(<foo>, bar));
>   
>     class-slot(<foo>, bar) := 21;
>     test("class-slot(<foo>, bar) := 21;", 
>          x.bar, class-slot(<foo>, bar));
>   end method main;
> 
> Which should output something like:
> 
>   define class-slot(<foo>, bar) as 10;
>       x.bar is 10
>       class-slot(<foo>, bar) is 10
>   x.bar := 15;
>       x.bar is 15
>       class-slot(<foo>, bar) is 15
>   class-slot(<foo>, bar) := 21;
>       x.bar is 21
>       class-slot(<foo>, bar) is 21
> 
> This should pretty much serve your needs, without getting into the
> strange territory. (Addition of stuff to deal with type declarations,
> each-subclass slots, and so on are left as an exercise for the
> reader. :)
> 
> 
> Neel
> 




References: