Quoting SV LRM.
It is always legal to assign an expression of subclass type to a
variable of a class type higher in the inheritance tree (a superclass
or ancestor of the expression type). It shall be illegal to directly
assign a variable of a superclass type to a variable of one of its
subclass types. However, $cast may be used to assign a superclass
handle to a variable of a subclass type provided the superclass handle
refers to an object that is assignment compatible with the subclass
variable.
When are the scenarios that the casting would fail when we try to assign super class instance to sub class instance? I understand whenever we try to cast two instances that are non-compatible with each other, casting would fail. Would casting fail anytime if they fall under same hierarchical tree? If so, may I know when?
You never make assignments to a class instance - you make assignments to a variable with a class type. The distinction is subtle but its important to know the difference between a class type and how that applies to a class variable and class instance.
The situation the LRM refers to is this
class A; endclass
class B extends A; endclass
class C extends A; endclass
A a_h;
B b_h;
C c_h;
b_h = new;
a_h = b_h; // always legal to go up the inheritance tree
$cast(b_h, a_h); // $cast required - will succeed
$cast(c_h, a_h); // $cast required - will fail
The second $cast fails because a_h holds a handle to a class instance of type B and is trying to assign it to a class variable of type C. This code is very simple but in a larger environment, it's not always easy to know what instance is being held in a_h and SystemVerilog requires a run-time check.
Related
I was wondering, if I define a new class variable, for example for the class MyClass, is the definition going to be in MyClass or in MyClass class? Does MyClass class even know about the new class variable?
Yes, class variables are shared with the class and the metaclass. They are also shared with all subclasses (and their metaclasses). A class variable is usually Capitalized, to convey better the idea of being shared in a scope broader than the class. You define class variables in the class (not the metaclass).
Class variables should not be confused with class instance variables, which are instance variables defined at the metaclass level, i.e., instance variables of the class object. This notion is somewhat obscure despite its simplicity (or because of it): instance variables are always defined in the class to define the shape (slots) of its instances. Thus, if we apply this definition to the metaclass, which is the class of the class, an instance variable defined here defines the shape of its instances, of which there is (usually) only one, the class.
Going back to class variables, you define them in the class (inst side) and initialize them in the metaclass (i.e., class side). Remember that these are (partial) globals in the sense that will be shared among instances, subinstances, subclasses and metaclasses and so they must be handled with the usual care we treat globals.
One more clarification
When we say that instance variables are shared among instances and subinstances, we mean their names (and positions in memory of the object slots); we don't mean their values (contents of said slots). Thus, two instances of the class C will share the name, say color, if the class defines the ivar color, but their values at each of the instances will be independent. In other words, what it is shared is the name, not the value.
With class variables what is shared is both the name and the value. It is actually the Association object, for example Theme -> aTheme, what's shared. In consequence, any modification to the value of a class variable affects all its references. This is not the case with class instance variables because they are nothing but instance variables, except that they shape the class and its subclasses, rather than regular instances and subinstances.
For more information on Smalltalk variables see https://stackoverflow.com/a/42460583/4081336
Just as a complement to Leandro's answer, here is the main Squeak implementation specific method that explains the sharing of class variables between instance side (class) and class side (metaclass):
Metaclass>>classPool
"Answer the dictionary of class variables."
^thisClass classPool
where thisClassis the unique instance of the Metaclass, that is the class itself...
There are high chances though to find similar implementation in most Smalltalk dialects.
The compiler will first try to resolve the variable as a method/block temporary (including methd/block parameters), then instance variables, then shared variables.
The classPool method is sent by the compiler in this last phase.
A Leandro did explain, the compiler either resolve the binding just as an offset that will be directly transcripted in the bytecode in case of instance variable slot or method temporary variable, or as a kind of Association for the shared variable case, this association being generally added to the CompiledMethod literals and effectively shared among all methods dealing with this variable (all methods points to the same Assocation object which is effectively shared).
The compiler part is much more dialect specific, in Squeak, it's this method which is used for resolving the binding of shared variables:
class>>bindingOf: varName environment: anEnvironment
"Answer the binding of some variable resolved in the scope of the receiver"
| aSymbol binding |
aSymbol := varName asSymbol.
"First look in local classVar dictionary."
binding := self classPool bindingOf: aSymbol.
binding ifNotNil:[^binding].
"Next look in local shared pools."
self sharedPools do:[:pool |
binding := pool bindingOf: aSymbol.
binding ifNotNil:[^binding].
].
"Next look into superclass pools"
superclass ifNotNil: [^ superclass bindingOf: aSymbol environment: anEnvironment].
"No more superclass... Last look in declared environment."
^anEnvironment bindingOf: aSymbol
This is to remind you that one of the most interesting part of Smalltalk is that you can dig into the implementation from within the IDE, Smalltalk is essentially written in Smalltalk!
I was looking through this example:
class SQLObject
def self.columns
return #columns if #columns
columns = DBConnection.execute2(<<-SQL).first
SELECT
"#{table_name}".*
FROM
"#{table_name}"
LIMIT
0
SQL
columns.map!(&:to_sym)
#columns = columns
end
def self.table_name
#table_name ||= self.name.underscore.pluralize
end
def insert
column_symbols = self.class.columns.drop(1)
column_names = column_symbols.map(&:to_s).join(", ")
question_marks = (['?'] * column_symbols.count).join(", ")
DBConnection.execute(<<-SQL, *attribute_values)
INSERT INTO
#{self.class.table_name} (#{column_names})
VALUES
(#{question_marks})
SQL
self.id = DBConnection.last_insert_row_id
end
end
And I was confused as to why it's ok to call the table_name method in the "self.columns" method as if it were an instance method. Isn't the "table_name" method a class method? Hence, shouldn't it be called as "self.class.table_name" in the "self.columns" method as well?
When inside an abstract class, the self refers to the proper class, not the object. That's why you can access the method without explicitly telling self
Short answer: self is the implicit receiver in Ruby. If you leave it out, the message will be sent to self. In other words, it is never necessary to say self.foo in a message send, because foo is always implicitly the same as self.foo.
Long answer: there is no such thing as a "class method" in Ruby. What you call a "class method" is actually nothing but a singleton method defined on an object which just happens to be an instance of the class Class.
Actually, there are no singleton methods in Ruby, either. A singleton method is really nothing but a regular old instance method which is defined on the singleton class of an object.
[Note: This is not to say that you should not use those terms. Saying "class method" is clearly simpler and communicates intent better than "instance method of the singleton class of an object of class Class". Also, note that there are methods such as Object#singleton_methods. Those terms clearly exist in the Ruby Community, but it is important to understand that these concepts do not exist in the Ruby Language. They are a tool for communication, not an actual Ruby concept.]
The singleton class is a class that is associated with an individual object. Each object has exactly one singleton class and that object is the only instance (the "singleton instance", hence the name) of its singleton class.
In fact, the inheritance hierarchy of an object always starts with its singleton class, i.e. the class pointer of an object always points to its singleton class, and the singleton class's superclass pointer then points to the class that created this object. You just don't see the singleton class in the inheritance chain, because methods like Object#class "skip over" the singleton class when calculating the inheritance chain. It is, however, always used during method lookup.
In fact, method lookup is actually very simple (the only exception is Module#prepend, which I am going to ignore for this explanation):
Dereference the receiver's class pointer.
If that class's method table has a method by the name of the message, invoke it. STOP.
If not, dereference the class's superclass pointer.
GOTO #2.
If you reach a class that doesn't have a superclass, restart the algorithm with the message method_missing(original_message_name, ...), unless the message name is already method_missing, in which case raise a NoMethodError.
So, it all comes down to two questions:
When defining a method, which class (or module) are you defining it in?
When sending a message, which object are you sending the message to?
When you define a method using def foo.bar, Ruby will first evaluate the expression foo and then define a method bar on the resulting object's singleton class (the definee). If you don't provide foo, i.e. you just say def bar, then bar is defined on the default definee, which is a little bit of a tricky concept. Normally, it is the closest lexically enclosing module definition. If there is no enclosing module definition, i.e. you are at the top-level, the default definee is Object and the method visibility is private.
When you send a message using foo.bar, Ruby will first evaluate the expression foo and then send the message bar to the resulting object (the receiver). If you don't provide foo, i.e. if you just say bar, then the default receiver is self.
Which brings us to the next question:
What is self?
Within a method definition body, self is the receiver of the message send that led to the invocation of this method. So, if you send the message foo.bar, then any reference to self in the definition of the method bar will, during this one execution of the method, evaluate to foo.
Within a module or class definition body, self is the class or method itself. (That is why defining a singleton method instance method of the singleton class using def self.bar works in a module or class definition body.)
Within a block or lambda literal, self is lexically captured, i.e. it is whatever self is at the point where the block or lambda literal is written. However, there are a couple of methods which change how self is evaluated, most notably the BasicObject#instance_eval, BasicObject#instance_exec, Module#module_eval, Module#module_exec, Module#class_eval, Module#class_exec, … family of methods.
If you are always aware of the answers to those three questions (where am I defining a method, what is the receiver of a method call, what is self) at any point in your code, then you have basically understood the most important parts of Ruby.
So, to put it all together:
At the point where you are defining the method using def self.columns, we are in a class definition body, so self refers to the class object itself (SQLObject).
The syntax def foo.bar defines a method bar on the singleton class of foo. In this case, you define the method columns on the singleton class of SQLObject. This means that the object SQLObject is the only object in the universe that will respond to the message columns.
Both of these also apply to the definition of self.table_name.
Inside of the method body of self.columns, self will dynamically refer to whatever the receiver is.
When you send the message columns to SQLObject, i.e. you write SQLObject.columns, then inside the body of the SQLObject::columns method, the receiver (i.e. self) will be set to SQLObject. (In this case, the receiver will always be SQLObject, since this is a method of a singleton class.)
So, inside the method body of self.columns, when you write the message send table_name, this is a message send with an implicit receiver. Since the implicit receiver is self, this is equivalent to self.table_name. self at this point is bound to SQLObject, so this is equivalent to SQLObject.table_name. In other words, the message is sent to SQLObject.
Now, per the algorithm I outlined above, the method lookup first retrieves the class pointer from SQLObject. As mentioned, the class pointer always points to the singleton class. So, we look inside the singleton class of SQLObject to see if we find a method named table_name, and we do!
Method lookup is finished, everything works.
I know objective c has built in 'init' method to initialize object. But i want to know In what circumstances do i need my own initializes to initialize object?
I want to know what value is assigned to self when i invoke 'self = [super init]'
You only need your own initializer when you need your object to default to a state that is different than what the compiler will enforce. That is, all instance variables are initialized to 0 (for integer-like types) or 0.0 (for floating point types). That means all pointers are nil and all numbers are 0(.0). If you need to initialize anything to a different value (creating internal container objects, for example), you need your own initializer.
Similarly, if your class inherits from a class that implements its own initializer, you only need your own if you want your state to be different than the superclass's.
Novice here attempting to understand inheritance. If I initialize a new object with several properties and I want other classes to help assign values to those properties, do I need to create instances of those other classes? Visualized:
-(ObjA *)init{
self = [super init];
self.property1 = [method from Class A];
self.property2 = [method from Class B];
self.property3 = [method from Class C]; etc...
return self;
}
In other words, assuming Class A, B, and C need to know what Object A is, would I need to make those class methods instance methods and initialize each object? Is there another way to go about this? Thank you in advance for your help.
In other words, assuming Class A, B, and C need to know what Object A
is
NO.
You can simply call a method from ClassA/B/C etc. But the return type must match with respective property.
Let, the property1 is for kind NSString then your ClassA method must be
-(NSString *)methodClassA{
...
return someStringValue;
}
Then you need to use:
ClassA *objClassA=[ClassA new];
self.property1=[objClassA methodClassA];
Or you can go with class method by this:
+(NSString *)methodClassA{
...
return someStringValue;
}
And using it as:
self.property1=[ClassA methodClassA];
assuming Class A, B, and C need to know what Object A is
The initialization code of an object should be self contained, unless it is using functionality owned by a different object, in which case the object acts as a client of that functionality. That is, objectA acts as client of A,B,C (as seen in your code).
But this doesn't imply that A,B,C need to know (have a dependency on) objectA. By doing that, you are saying that they don't have a reason to exist on their own.
In general,
Every class or method should have one encapsulated purpose. This makes it easy to understand, change, and test in isolation. It's a common pattern to create classes whose sole purpose is to encapsulate information to create a different class, but to split that in three different classes is beyond weird (as in, I can't imagine an example of that).
An object shouldn't be allowed to exist in an unusable state, nor should it require non essential information when it is created. Does objectA require those properties to function? if it does, your code is right, if it doesn't, the initializer is providing too much information and making it less reusable.
Try to rethink your doubt with a real (instead abstract) example. You may end up making sense of it yourself.
When a new object is created and initialized why do we use id? Can't we use (NSObject*)?
Not every object in Objective C is NSObject. There are other root classes (for example, NSProxy), that are not derived from NSObject.
id means absolutely any object. Everything is Objective C that can receive messages (including Class) can be passed as id without type warnings.
NSObject* is only useful on objects that are actually derived from NSObject. If you pass something that is not derived from it, type checker will complain.
Because NSObject is a distinct Objective C class. It's the base class for most everything (* but not everything, +1 to HamsterGene), but it's still a class.
And if you assigned a new object (of any type that descends from NSObject) to it, you'd lose the inheritence & properties of whatever subclassed type you had created were.
id is roughly equivalent to void * in it's behavior where you can assign any Objective C object to an id, like how you can assign any random chunk of memory (with no care for it's contents or type) to a void *.