Unable to resolve error "target of assigner call has no associated assigner command" in Eiffel - class

In Eiffel Studio, I have been trying to access the fields of an object of a class I have defined from another class. However, it keeps giving errors that I am not able to understand and solve. The following is a snippet of example code:
Class where object is being created:
class
TEST1
feature
object: TEST2
-- object of type TEST2
function(val: INTEGER)
-- Assign
do
object.value:=val
end
end
Class whose object is being created:
class
TEST2
feature
value: INTEGER
end
The error messages are as follows:
Error code: VBAC(2)
Error: target of assigner call has no associated assigner command.
What to do: add an assigner mark to the declaration of the target feature or use a dot form of a call.
Class: TEST1
Feature: function
Line: 10
do
-> object.value:=val
end
and
Error code: VEVI
Error: variable is not properly set.
What to do: ensure the variable is properly set by the correspondig setter instruction.
Class: TEST1
Source class: ANY
Feature: default_create
Attribute(s): object
Line: 331
do
-> end
It seems that there is some problem with the assignment statement. However, I haven't been able to understand what is wrong.
The classes have been defined in different files under the same cluster of the same project. I am new to Eiffel, so I don't know if this could be the problem.
Thank you.

In Eiffel, every attributes are considerate as Read-Only. This remove the need to create getters like you do in other languages like Java. To assign a value to an attribute using the ":=" syntaxe, you will need an assigner. Here an example:
class
TEST2
feature
value:INTEGER assign set_value
set_value(a_value:INTEGER)
do
value := a_value
end
end
Then, you will be able to use the line:
object.value:=val
For the second error, by default, EiffelStudio is what we call Void Safe. This is a mecanism that ensure that an attribute that is not considerated as "detachable" will never be Void (similar to NULL in other languages). By default, every class have the default constructor called "default_create" and this constructor does not do anything. What you have to do, is creating you own constructor in the {TEST1} class that instanciate every attribute inside it. Here is an example:
class
TEST1
create
make
feature
make
do
create object
end
object: TEST2
-- object of type TEST2
function(val: INTEGER)
-- Assign
do
object.value:=val
end
end
In the preceding example, I created a method call make, specify that the method is the constructor and in this method, I make sure that the object attribute is correctly instanciate.

Related

Why do some Matlab class methods require "apparently" unnecessary output argument

After evolving my project code for months, I've finally hit a need to define a new class. Having to romp through my previous class definitions as a refresher of the conventions, I noticed that all constructors and property setters all have an output argument, even though nothing is assigned to it, e.g.:
function o = myConstructor( arg1, arg2, ... )
function o = set.SomeProperty( o, arg1 )
I've been looking through the documentation for upward of an hour without finding the explanation for this. It doesn't look like it depends on whether a function is defined in the class definition file or in its own separate m-file.
Can anyone please explain?
The best place to start is the documentation "Comparison of Handle and Value Classes". From the very top:
A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLABĀ® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument.
A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.
In other words, value classes need to return a modified object (which is a new object distinct from the original), while handle classes don't. The constructor of either class will always have to return an object, since it is actually constructing it.
Some good additional reading is "Which Kind of Class to Use", which links to a couple helpful examples of each type of class object. Looking at the DocPolynom value class example, you can see that property set methods have to return the modified object, while the dlnode handle class example only requires an output for its constructor. Note that you could still return an object from a handle class method (if desired), but it's not required.

Import class to access constant values

I defined a class in one of my many MATLAB packages. To my suprise, I could not access a constant property of my class without importing the class definition. Even if it is a method of the class itself. Like so:
classdef TestClass
properties( Constant )
c=0;
end
methods
function obj = TestClass()
end
function getC(obj)
import test.TestClass;
disp(TestClass.c);
end
end
end
I just want to check whether I am doing something wrong here or is this the correct way to use constants in MATLAB.
Since you have placed TestClass inside a package Matlab needs to know where to look to find the definition for this class, even if it's a reference from within the class or function. An alternate to the above code could be:
function getC(obj)
disp(test.TestClass.c);
end
Alternately, if within a class, constant values can be accessed from the object itself.
function getC(obj)
disp(obj.c);
end
If neither of these is working for you, you may need to refresh the classdef for TestClass from memory. This will cause matlab to reload the constant value, which is pulled into Matlab when it first parses the classdef file to determine the structure of the class. This can be done using clear classes, however a warning that it will also clear all other classes, variables, and any breakpoints you have set.
If you want to see if this is necessary you can view the metaclass object to determine what Matlab "thinks" your class structure should be. You can do this using the following.
mc = ?test.TestClass;
mc.PropertyList
You may need to index into the property list to find the specific property you are interested in, but the thing you are looking for are the following fields.
Name: 'c'
Constant: 1
DefaultValue: 0

Should it be possible to call an instance method of a class without creating a new object of that class?

I can do this and I don't have any issues:
class MyClass:
def introduce(self):
print("Hello, I am %s, and my name is " %(self))
MyClass.introduce(0)
MyClass().introduce()
I'm using Visual Studio and Python 3.4.1. I don't understand why this doesn't throw an error since I'm basically setting the value of this. Is this a feature and I just shouldn't be doing this? Should I be checking if self is actually an instance of MyClass?
In Python 3 when you do MyClass.introduce() introduce is not linked to any object. It's considered as a (standalone) function like any other function you would declare by itself. The fact that it is declared within a class is not relevant here. introduce is therefore called like any function: a function with one parameter.
When you do MyClass().introduce() (notice the first set of parentheses) introduce is considered as a method belonging to an object which is an instance of class MyClass hence the regular OO behavior of adding automatically the self parameter.
Note that this is different for python 2. In python 2 there is a check to verify that when called, the effective argument passed for the self parameter is indeed an object of the correct type, i.e. an instance of MyClass. If you try MyClass.introduce(0) in Python 2 you'll get: unbound method introduce() must be called with MyClass instance as first argument (got int instance instead). This check doesn't exist in Python 3 anymore because the notion of unbound method no longer exist.

YUI autocomplete plugin is undefined

My vary simple code: var ac = Y.Plugin.AutoComplete("searchInput", "results");
ERROR: Uncaught TypeError: Object # has no method 'AutoComplete'
do I need to include some specific js file or...?
This probably means you're not calling it the right way. Although I didn't use it before, the documentation says it only takes one parameter, not two strings. See AutoComplete API :
init ( config ) Base
Inherited from BaseCore but overwritten in base/js/Base.js:191
Init lifecycle method, invoked during construction. Fires the init
event prior to setting up attributes and invoking initializers for the
class hierarchy. Parameters:
config Object
Object with configuration property name/value pairs
Returns: Base: A reference to this object
So you should try to create a config object and pass it as parameter.
Alexis

Can instances get their own copy of class level mutable defaults without using __init__?

I'm writing a metaclass to do some cool stuff, and part of its processing is to check that certain attributes exist when the class is created. Some of these are mutable, and would normally be set in __init__, but since __init__ isn't run until the instance is created the metaclass won't know that the attribute will be created, and raises an error. I could do something like:
class Test(meta=Meta):
mutable = None
def __init__(self):
self.mutable = list()
But this approach has several problems:
it forces the creation of a class attribute that is not the same type as the instance attribute
__init__ still has to shadow the class attribute, and Meta is not checking that
if __init__ doesn't shadow the class attribute I'll still get errors down the line (such as AttributeError: 'NoneType' object has no attribute 'append'), and trying to avoid such errors is part of the function of Meta
and last but not least, it violates DRY.
What I need is a way to have something like:
class Test(metaclass=Meta):
mutable = list()
But each instance will end up with its own copy of mutable.
The design goals are:
the attribute must exist in the class (type doesn't matter -- it is not checked)
at some point before the attribute is first used a copy of the attribute is placed in the instance
A desired sample run:
t1 = Test()
t2 = Test()
t1.mutable.append('one')
t2.mutable.append('two')
t1.mutable # prints ['one']
t2.mutable # prints ['two']
Any ideas on how this can be accomplished?
There are at least three ways to do this:
Have the metaclass check all the attributes, and if they are one of the mutables (list, dict, set, etc.) replace the attribute with a descriptor that will activate on first access and update the instance with a fresh copy of the mutable.
Provide the descriptor from (1) as a decorator to be used when writing the class.
Have the metaclass add its own __init__ method to the class which when run:
calls the original __init__
then checks that the required attributes are present
Downsides (by method):
Extra effort is required if the class has a mutable attribute that should be shared across all instances.
The attribute in the class becomes a function in the class (possible mind-warp ;)
Move the point of error to class instantiation instead of class definition.
I prefer (2) is it gives complete control to the class author, simplifies those cases where the class-level mutable attribute should be shared amongst all the instances, and keeps the error at class definition.
Here's the decorator-descriptor:
class ReplaceMutable:
def __init__(self, func):
self.func = func
def __call__(self):
return self
def __get__(self, instance, owner):
if instance is None:
return self
result = self.func()
setattr(instance, self.func.__name__, result)
return result
and the test class:
class Test:
#ReplaceMutable
def mutable():
return list()
How it works:
Just like property, ReplaceMutable is a descriptor object with the same name as the attribute it is replacing. Unlike property, it does not define __set__ nor __delete__, so when code tries to rebind the name (mutable in the test above) in the instance Python will allow it to do so. This is the same idea behind caching descriptors.
ReplaceMutable is decorating a function (with the name of the desired attribute) that simply returns whatever the instance level attribute should be initialized with (an empty list in the example above). So the first time the attribute is looked up on an instance it will not be found in the instance dictionary and Python will activate the descriptor; the descriptor then calls the function to retrieve the initial object/data/whatever, stores it in the instance, and then returns it. The next time that attribute is accessed on that instance it will be in the instance dictionary, and that is what will be used.
Sample code:
t1 = Test()
t2 = Test()
t1.mutable.append('one')
t2.mutable.append('two')
print(t1.mutable)
print(t2.mutable)