What's the trick / catch ... if there is one for invoking a class method from a workspace?
I created a Class "MikeTest". - Added an instance method : "imethod" MikeTest >> imethod ^ 'I am an instance method' - Added a Class method MikeTest class>>cmethod ^ 'I am a class method' ---- Then in a workspace : t := MikeTest new. t imethod (alt-p) -->> 'I am an instance method' (As expected) t cmethod (alt-p) gives 'MessageNotUnderstood' http://mstram.freepgs.com/img/message_not_understood_when_evaluating_class_method.jpg The debug trace has 'UndefinedObject>>Doit' ... which seems strange to me ... does that mean the workspace doesn't understand how to send a class method ??? Puzzled (again). Mike |
El 5/26/07 9:50 AM, "mstram" <[hidden email]> escribió: > > What's the trick / catch ... if there is one for invoking a class method from > a workspace? > > I created a Class "MikeTest". > > - Added an instance method : "imethod" > > MikeTest >> imethod > ^ 'I am an instance method' > > - Added a Class method > > MikeTest class>>cmethod > ^ 'I am a class method' > > ---- > Then in a workspace : > > t := MikeTest new. > t imethod (alt-p) -->> 'I am an instance method' (As expected) > > t cmethod (alt-p) gives 'MessageNotUnderstood' > > http://mstram.freepgs.com/img/message_not_understood_when_evaluating_class_met > hod.jpg > > The debug trace has 'UndefinedObject>>Doit' ... which seems strange to me > ... does that mean > the workspace doesn't understand how to send a class method ??? > > Puzzled (again). > > Mike do MikeTest cmethod. Edgar _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by mstram-2
Hi mstram,
on Sat, 26 May 2007 14:50:34 +0200, you wrote: > What's the trick / catch ... if there is one for invoking a class method > from > a workspace? > > I created a Class "MikeTest". > > - Added an instance method : "imethod" > > MikeTest >> imethod > ^ 'I am an instance method' > > - Added a Class method > > MikeTest class>>cmethod > ^ 'I am a class method' > > ---- > Then in a workspace : > > t := MikeTest new. > t imethod (alt-p) -->> 'I am an instance method' (As expected) > > t cmethod (alt-p) gives 'MessageNotUnderstood' > > http://mstram.freepgs.com/img/message_not_understood_when_evaluating_class_method.jpg > > The debug trace has 'UndefinedObject>>Doit' ... which seems strange to me > ... does that mean > the workspace doesn't understand how to send a class method ??? The line with UndefinedObject>>DoIt is how the compiler invokes the expression when you do (alt-p). When you select that line, you can see your expression decompiled. So, no problem. The other question was answered by Edgar. /Klaus > Puzzled (again). > > Mike _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by mstram-2
On May 26, 2007, at 14:50 , mstram wrote:
> What's the trick / catch ... if there is one for invoking a class > method from > a workspace? "Class methods" in Smalltalk are regular methods, because classes are regular objects. Unfortunately the browser gives the impression that there are two kinds of methods ... MyClass new simply sends #new to the object MyClass. This is how you invoke a "class method". Remember, anything in Smalltalk is an object. Even classes. There is not even a "syntax" to define a class or a method (just like there is no syntax for control structures). Everything is accomplished by sending messages. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Edgar J. De Cleene
Ok thx, have it working now. Though I ran into an error when I tried to use : do MikeTest cmethod. and changed it to just MikeTest cmethod. :) also : avar := MikeTest cmethod also works, as I'm sure you know .. but took me a minute to think of ;) Mike |
In reply to this post by Bert Freudenberg
Well obviously I need to a lot more reading and experimenting with this,
even if "class" methods are "regular" methods, there is something different with them as far as : 1) the syntax to access them ("fire" .. "call" .. "invoke" ??? what is the traditional term ? ) 2) At least one difference I've found is that I when tried to create a "class" method that accessed an instance variable, Squeak warned that the variable didn't exist and asked if I wante to create it (is this a bug?) ... even though it was "declared" in the class definition. I tried modifying my MikeTest to : Object subclass: #MikeTest instanceVariableNames: 'ivar1' classVariableNames: 'Cvar1' poolDictionaries: '' category: 'Mike1' and adding : A) -----------"instance method " ------------------------------- imet: ivar icmet: cvar ivar1 := ivar. Cvar1 := cvar. ^ 'I am an instance method' --------------------------------------------- iget |temp| temp := Dictionary new. temp at: 'ivar1' put: ivar1. temp at: 'cvar1' put: Cvar1. ^ temp. and B) --------------"class method " -------------------------------- cmet: ivar ccmet: cvar ivar1 := ivar. Cvar1 := cvar. Cvar1 := cvar. ^ 'I am a Class Method' -------------------------------------------------------------- cget |temp| temp := Dictionary new. temp at: 'cvar1' put: Cvar1. temp at: 'ivar1' put: ivar1. ^ temp. ================================= (I realize 'iget' and 'cget' are the same thing, I just wanted to see if there is any difference when running them.) But Squeak says that 'ivar1' is undeclared and asks if I want to declare it. It accepts it being declared as an instance variable (even though it already was according to the class definition ... (is this a bug?). I can set / retrieve the variables with either the "class" or "instance" methods, so I'm not sure why Classes have been setup in Squeak using both types of methods. t1 := MikeTest new. result := MikeTest cmet: 'Class method setting inst var ivar1-> inst44' ccmet: 'Class method setting class var Cvar1 -> Class01'
|
On May 26, 2007, at 18:32 , mstram wrote: > > Well obviously I need to a lot more reading and experimenting with > this, > even if "class" methods are "regular" methods, there is something > different > with them as far as : > > 1) the syntax to access them ("fire" .. "call" .. "invoke" ??? > what is the > traditional term ? ) There is no special syntax. The only difference is the receiver. Either you send a message to an instance of a class or or the class itself (which, as mentioned before, is a regular object). > 2) At least one difference I've found is that I when tried to create a > "class" method that accessed an instance variable, Instance variables are private, they can only be accessed by the object itself. So from the class object you cannot access instance variables of one of its instances. > Squeak warned that the variable didn't exist and asked if I wante > to create it (is this a bug?) ... > even though it was "declared" in the class definition. > [...] > But Squeak says that 'ivar1' is undeclared and asks if I want to > declare it. > It accepts it being declared as an instance variable (even though > it already > was according to the class definition ... (is this a bug?). No, what you did there is you defined 'ivar1' as an instance variable of the class object itself, not for instances of your class. It will be listed in the browser when you switch to the class side definition. This feature is very rarely used. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by mstram-2
On Saturday 26 May 2007 10:02 pm, mstram wrote:
> 2) At least one difference I've found is that I when tried to create a > "class" method that accessed an instance variable, Squeak warned that the > variable didn't exist and asked if I wante to create it (is this a bug?) > ... even though it was "declared" in the class definition. Mike, Think of instantiation and declaration as being like icecream and its récipé. You can make many cups of icecreams from the same récipé. The instance variable (cherry) declared in the class definition (récipé) will be created only when a object of this class is created (icecream pie). You cannot assign to an instance variable in a class method anymore than you can eat cherries from a récipé :-). You 'browse' a récipé and 'inspect' or 'explore' the icecream :-). This analogy doesn't apply exactly to Squeak. Since classes are also objects that are created when you 'accept' the definition (except that its variables are created from classVariableNames), so you can use them in class methods immediately. Like Bert explained in an earlier mail, use of classVariables is very rare. Enjoy .. Subbu _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On May 27, 2007, at 17:14 , subbukk wrote:
> Since classes are also objects > that are created when you 'accept' the definition (except that its > variables > are created from classVariableNames), so you can use them in class > methods > immediately. Not quite. Those variables are "class variables", which are global variables (global to the class and subclasses and all their instances). Their names start with a capital letter like every global variable in Smalltalk. > Like Bert explained in an earlier mail, use of classVariables is > very rare. There is a difference between "class variables" (which are like "static" variables in other systems, so they get their fare share of use) and "class instance variables" (very rarely used indeed). You see "class instance variables" only when you switch the browser to the class side. "Class instance variables" have a different value in each subclass and are private to the class-side. Hence they are not global and have lower-case names. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Sunday 27 May 2007 9:44 pm, Bert Freudenberg wrote:
> There is a difference between "class variables" (which are like > "static" variables in other systems, so they get their fare share of > use) and "class instance variables" (very rarely used indeed). You > see "class instance variables" only when you switch the browser to > the class side. "Class instance variables" have a different value in > each subclass and are private to the class-side. Hence they are not > global and have lower-case names. Thank you for explaining this in detail. I missed the fact that instance variables listed by browser on the class side are different from those on the instance. If I understood this correctly: (class instance) variables - variables global to all objects instantiated from a class class (instance variable) - instance variable of the class (treated as an object and therefore visible only to its methods and methods in its subclasses). BTW, I used the code below to inspect classes with explicit CIVs: (Smalltalk values select: [ :c | (c isKindOf: Class) and: [c class allInstVarNames size > 13 ] ]) collect: [ :d | { d . d class allInstVarNames size} ] but this gave me classes that inherit them too. Is there a way to tease out classes that *define* CIVs? Regards .. Subbu _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Hi, Subbu,
Try: ClassListBrowser browseClassesSatisfying: [:cl | cl class instVarNames size > 0] title: 'classes defining class-side inst vars' Cheers, -- Scott On Jun 4, 2007, at 10:40 AM, subbukk wrote: > BTW, I used the code below to inspect classes with explicit CIVs: > (Smalltalk values select: [ :c | > (c isKindOf: Class) and: [c class allInstVarNames size > 13 ] ]) > collect: [ :d | { d . d class allInstVarNames size} ] > > but this gave me classes that inherit them too. Is there a way to > tease out > classes that *define* CIVs? > > Regards .. Subbu > _______________________________________________ > Beginners mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/beginners _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by K. K. Subramaniam
On Jun 4, 2007, at 19:40 , subbukk wrote: > On Sunday 27 May 2007 9:44 pm, Bert Freudenberg wrote: >> There is a difference between "class variables" (which are like >> "static" variables in other systems, so they get their fare share of >> use) and "class instance variables" (very rarely used indeed). You >> see "class instance variables" only when you switch the browser to >> the class side. "Class instance variables" have a different value in >> each subclass and are private to the class-side. Hence they are not >> global and have lower-case names. > Thank you for explaining this in detail. I missed the fact that > instance > variables listed by browser on the class side are different from > those on the > instance. If I understood this correctly: > (class instance) variables - variables global to all objects > instantiated > from a class This sounds more like "class variables". > class (instance variable) - instance variable of the class > (treated as an > object and therefore visible only to its methods and methods in its > subclasses). I don't think that is correct - what do you mean by "treated as an object"? I may be repeating myself, but *everything* is "treated as an object", because it is. There really is only a difference between local and global variables. Local vars are lowercase by convention and local to an object instance ("instance variables") or a method activation ("temporary variables", "arguments"). There are special byte codes to access them. Global variables are uppercase by convention and are actually Associations (key->value pairs) held in dictionaries known to the compiler, and the Association gets stored as literal in a CompiledMethod. Their "globalness" differs in what dictionary ("variable pool") they live in - the one called "Smalltalk", or the "classPool" inst var of classes (these are "class variables"), or in shared pools (pools that are listed in the "sharedPool" class inst var, or whatever other dictionaries where given to the compiler (like "References" for etoys scripts). > BTW, I used the code below to inspect classes with explicit CIVs: > (Smalltalk values select: [ :c | > (c isKindOf: Class) and: [c class allInstVarNames size > 13 ] ]) > collect: [ :d | { d . d class allInstVarNames size} ] > > but this gave me classes that inherit them too. Is there a way to > tease out > classes that *define* CIVs? Smalltalk allClasses select: [:ea | ea class instVarNames size > 0] So one of them is Beeper. Just do a "Beeper inspect" to see its class inst vars, or to see which superclass defines what, do: Beeper class withAllSuperclasses collect: [:ea | ea -> ea instVarNames] an OrderedCollection( Beeper class->#('default') Object class->#() ProtoObject class->#() Class->#('subclasses' 'name' 'classPool' 'sharedPools' 'environment' 'category') ClassDescription->#('instanceVariables' 'organization') Behavior->#('superclass' 'methodDict' 'format') Object->#() ProtoObject->#() ) - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Tuesday 05 June 2007 1:21 am, Bert Freudenberg wrote:
> > class (instance variable) - instance variable of the class > > (treated as an > > object and therefore visible only to its methods and methods in its > > subclasses). > > I don't think that is correct - what do you mean by "treated as an > object"? I may be repeating myself, but *everything* is "treated as > an object", because it is. In Smalltalk, classes are first order objects. I need to keep reminding myself about this :-) because in many imperative languages this is not true. > Smalltalk allClasses select: [:ea | ea class instVarNames size > 0] Thanks for this hint. This is what I needed: Smalltalk allClasses select: [ :c | c class instVarNames size > 0 ] thenCollect: [ :c | c -> c class instVarNames ]. I had dropped the 'class' method and instVarNames didn't work. No wonder. 28 classes out of 2043 define their own instance variables. Rare indeed! Thanks a lot .. Subbu _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Jun 5, 2007, at 7:55 , subbukk wrote: > On Tuesday 05 June 2007 1:21 am, Bert Freudenberg wrote: >>> class (instance variable) - instance variable of the class >>> (treated as an >>> object and therefore visible only to its methods and methods in its >>> subclasses). >> >> I don't think that is correct - what do you mean by "treated as an >> object"? I may be repeating myself, but *everything* is "treated as >> an object", because it is. > In Smalltalk, classes are first order objects. I need to keep > reminding myself > about this :-) because in many imperative languages this is not true. > >> Smalltalk allClasses select: [:ea | ea class instVarNames size > 0] > Thanks for this hint. This is what I needed: > Smalltalk allClasses select: [ :c | c class instVarNames size > 0 ] > thenCollect: [ :c | c -> c class instVarNames ]. > > I had dropped the 'class' method and instVarNames didn't work. No > wonder. > 28 classes out of 2043 define their own instance variables. Rare > indeed! And even of these few, some are in error and should really be class vars instead. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |