Pharo Smalltalk - How is variable scope in an Object achieved? - smalltalk

I'm experimenting in Pharo and I was wondering how class, instance variable scope is achieved.
More to the point, instance variables can be accessed by all the methods of that instance of a class, also class instance variables can be accessed by all the methods of the class and so on.
Where does the depth of this scope get defined in code? Can one see where and how this takes place, Smalltalk being fully Object Oriented?

I presume you are in Pharo >= 4.0, in which case you have the so called OpalCompiler.
In OpalCompiler, the variable scope is reified (see OCAbstractScope and subclasses), the scope being used during semantic analysis of the Abstract Syntax Tree (see OCASTSemanticAnalyzer).
You now have an entry point, and should follow message senders, class refs, instance variable refs, ... from this starting point.

Related

How to get only declared members (not inherited) with Kotlin Reflection?

Is there any way to get only the declared members of a class (not inherited) with Kotlin Reflection?
Something equivalent to getDeclaredMethods(), or ...Fields(), in Java, but for members and JVM free, which:
Returns an array containing Method objects reflecting all the declared methods of the class ... but excluding inherited methods.
Or like a binding flag, such as BindingFlags.DeclaredOnly of dotnet.
Because the reflection is based on the class, So the following is only for the kotlin/JVM, not suitable for the Kotlin/JS or Kotlin/Native.
For the Kotlin/JS it supports limit, for detail, you can see this
document
The only supported parts of the API are: (::class),KType and typeOf
Firstly, you can use the SomeClass::class.java.declaredMethods to get the
getDeclaredMethods. That is the java method. Because the Kotlin file after compiled it is still a class. so you can directly use it.
You can also add the kotlin reflect to get the KClass, then use the declaredFunctions to get. Here is the Document
Returns all functions declared in this class. If this is a Java class, it includes all non-static methods (both extensions and non-extensions) declared in the class and the superclasses, as well as static methods declared in the class
For how to get the KClass, you can use the following code
Class.forName("mypackage.MyClass").kotlin.declaredFunctions
Besides the method, the other property you can also get. such as
declaredMembers
Returns all functions and properties declared in this class. Does
not include members declared in supertypes.
allSuperclasses
functions
Returns all functions declared in this class, including all non-static methods declared in the class and the superclasses, as well as static methods declared in the class.
you can read the document using it.

Global variables in Kotlin

After using Java for a long time I almost forgot how it is to be allowed to define global variables. I read that it is recommended to use top-level functions in Kotlin instead of wrapping them inside objects like in Scala. How about top-level variables (which I guess we call global variables)? What is the recommendation about using them? What are the pitfalls? How are they deallocated?
Global variables are supposed to be accessible from anywhere at any point in your program, so it would most likely be a bad idea to deallocate global variables, even if you could because it could lead to instability or crashes in your application.
Now Kotlin is a JVM language, it compiles to Java code and therefore is garbage-collected. As for how the garbage collector works, when a variable is no longer referenced by the program, it gets flagged for deletion and will be removed by the garbage collector later (not necessarily instantly).
Global variable's scope is the entire program so they are never garbage-collected. What could you do tho is to set its reference to null (if it is declared nullable) to allow at least the referenced memory to be collected.
The top-level variables that you are referring about aren't exactly free since Kotlin will compile them into a java class named with the file name anyway(that's how you can access kotlin file-specific functions inside java code), so they are just like static fields in Java. For a better explanation you could check this thread: Kotlin: Difference between constant in companion object and top level.
Now we know that top-level variables are compiled into static variables inside a Java class. Those don't get flagged for collection unless the program somehow drops the class loader associated to that class itself but that's something I can't speak of more since I never used that.
Now in the end, should you use global variables? They are usually considered a bad practice and this is in big part due to the fact that they can be referenced by any part of the program and it can be hard to remember when and why did they change, especially in large applications. If you keep track of their usages and use them in moderation then they are alright. Personally, if I have to use them, I define them inside a class as a companion object the same way you would define static variables in java, like this:
class GlobalData {
companion object {
var varEx= 0
const val constString = "CONSTANT GLOBAL"
}
}

Changing a class variable from outside the class

Finally, when I managed to understand how to fix this, that is, how to change the value of an internal dynamic variable, the code has moved on and now it is declared in this way:
my int $is-win = Rakudo::Internals.IS-WIN;
This is a class variable declared inside class Encoding::Builtin. Makes all the sense in the world, since an OS is not something that changes during the lifetime of a variable. However, I need to test this code from other OS, so I would need to access that class variable and assign it a True value. Can I do that using the meta object protocol?
The concept of "class variable" doesn't exist in Perl 6.
The declaration being considered is of a lexical variable, and its lifetime is bound to the scope (bounded by curly braces) that it is declared within. It doesn't have any relationship with the class that's being declared, so there's no way to reach it through the MOP. (That the block in this question happens to be attached to a class declaration is incidental so far as lexical variables go.) Nor is it declared our, so it's not stored in the package either.
The only way a lexical can be accessed - aside from under a debugger - is if something inside of that lexical scope explicitly made it possible (for example, by acquiring a pseudo-package and storing it somewhere more widely visible, or by allowing EVAL of provided code). Neither is happening in this case, so the variable not possible to access.
Perl 6 is very strict about lexical scoping, and that's a very intentional part of the language design. It supports the user in understanding and refactoring the program, and the compiler in program analysis and optimization. Put another way, Perl 6 is a fairly static language when it comes to lexical things (and will likely come to do much more static analysis in future language versions), and a dynamic language when it comes to object things.

new and initialize in smalltalk - how to pass parameters to initialize

In smalltalk, when we create a object by calling new which calls initialize . I want to initialize but with my own parameters(passed at run time). How can I do that.
e.g. Myobjcet new
but how do I pass parameters to this so they get passed to initialize.
I am using Pharo.
If I recall, reimplementing class methods new and initialize should be avoided.
Instead, you can create your own class method (other than new or initialize) that takes parameters, and use those when creating your new instance. For example in Squeak look at the class method with: for class Collection. It first creates a collection instance, and then adds to the instance the object passed as an argument.
with: anObject
"Answer an instance of me containing anObject."
^ self new
add: anObject;
yourself
Your Pharo maybe based on Squeak, so you should find the same, or a similar class method for Collection in your image.
Correctly writing the instantiation and initialization code of complex object hierarchies is tricky in Smalltalk. What is more, the default initialization logic as implemented in Object is different across different Smalltalk dialects (i.e. Pharo decided to introduce a default initializer, making things worse).
To avoid confusion and to have clear and consistent rules the Seaside team decided to apply the following rules for all their code:
Object-Initialization at Seaside
Also the Seaside code includes Code Critic rules that check for mistakes in the use of the proposed initialization pattern.

specific questions about scope and property reference in actionscript 3

I've been battling with AS3 for a little while now, and I'm working on a simple application using only actionscript and the FlashDevelop/flex-compiler combo. I've hit a bit of a wall in my fledgling OOP understanding, and I'm wondering whether someone might be able to point me in the right direction. I have genuinely read several books, and spent many hours reading online tutorials etc, but something's just not clicking!
What's baffling me is this: When something is declared 'public', according to what I read, it is therefore available anywhere in the application (and should therfore be used with care!) However, when I try to use public properties and methods in my program, they most definitely are not available anywhere other than from the class/object that instantiated them.
This leads me to conclude that even if objects (of different class) are instantiated from the same (say 'main') class, they are not able to communicate with each other at all, even through public members.
If so, then fair enough, but I've honestly not seen this explained properly anywhere. More to the point, how do different objects communicate with other then? and what does Public actually mean then, if it only works through a direct composition hierarchy? If one has to write applications based only on communication from composer class to it's own objects (and presumably use events for, er, everything else?) - isn't this incredibly restrictive?
I'm sure this is basic OOP stuff, so my apologies in advance!
Any quick tips or links would be massively appreciated.
There are different topics you are covering in your question. Let me clarify:
What does the modifier public mean?
How can instances of the same class communicate to each other?
--
1.
In OOP you organize your code with objects. An object needs to be instantiated to provide its functionality. The place where you instantiate the object can be considered as the "context". In Flash the context might be the first frame, in a pure AS3 movie, it might be the main class, in Flex it could be the main mxml file. In fact, the context is always an object, too. Class modifier of your object public class MyClass tells your context whether it is allowed to instantiate the object or not. If set to internal, the context must live in the same directory as the class of the object. Otherwise it is not allowed to create a new object of the class. Private or protected are not valid class modifiers. Public class ... means that any context may create an object of that class. Next: Not only instantiation is controlled by these modifiers but also the visibility of a type. If set to internal, you cannot use an expression like var obj : InternalType in a context that does not live in the same directory as Internal type.
What about methods and properties? Even if your context is allowed to access a type, certain properties and methods might be restricted internal/protected/private var/method and you perhaps are not able to invoke them.
Why we're having such restrictions? Answer is simple: Differnent developers may develop different parts of the same software. These parts should communicate only over defined interfaces. These interfaces should be as small as possible. The developer therefore declares as much code as possible to be hidden from outside and only the necessary types and properties publicly available.
Don't mix up with modifiers and global properties. The modifier only tells you if a context is allowed to see a type or method. The global variable is available throughout the code. So even if a class is declared to be public, instances of that class do not know each other by default. You can let them know by:
storing the instances in global variables
providing setter such as set obj1(obj1 : OBJ1) : void where each object needs to store the reference in an instance variable
passing the object as method arguments: doSomething(obj1 : OBJ1)
Hope this helps you to more understand OOP. I am happy to answer your follow up questions.
Jens
#Jens answer (disclaimer: I skimmed) appears to be completely correct.
However, I'm not sure it answers your question very directly, so I'll add a bit here.
A public property is a property of that class instance that is available for other objects to use(function: call, variable: access, etc). However, to use them you must have a reference (like a very basic pointer, if that helps?) to that object instance. The object that instantiates (creates, new ...) that object can take that reference by assigning it to a variable of that class type.
// Reference is now stored in 's'
public ExampleClass s = new ExampleClass();
If you'd like to, you do have the option of making a static property, which is available just by knowing the class name. That property will be shared by all instances of that class, and any external class can refer to it (assuming it's public static) by referring to the class name.
A public property is referred to by the reference you stored.
//public property access
s.foo
s.bar(var)
A static property is referred to by the class name.
//static property access
ExampleClass.foo
ExampleClass.bar(var)
Once you've created the instance, and stored the reference, to an object, you can pass it around as you'd like. The below object of type OtherExampleClass would receive the reference to 's' in its constructor, and would have to store it in a local variable of its own to keep the reference.
public OtherExampleClass s2 = new OtherExampleClass(s);