[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: