Question about classes and this

Hi there !

Starting writing my classes…

Let’s take this simple class

TestClass {
	var <myVar;

	*new { |myVar = 0|
		^super.newCopyArgs(myVar);
	}

	myVar_ { |v|
		myVar = v;
	}
}

I can use it like this

t = TestClass.new;
t.myVar;
-> 0
t.myVar = 3;
t.myVar;
-> 3

Good.

In some other languages, I can make the distinction between instance variables and the function variables with the keyword this, it would allow me to write the myVar_ setter like this

	myVar_ { |myVar|
		this.myVar = myVar;
	}

It does not work, it hangs sclang, because it goes into a feedback loop (which I understand).

Can I use something other than this. to use the same variable name as a function parameter ?

Thanks !

Geoffroy

1 Like

You can refer to internal slots of a class by using the variable name directly e.g. myVar - so your myVar_ setter should be:

myVar { ^myVar }
myVar_{ |v| myVar = v }

Also note that you can automatically define trivial getter/setters for properties using angle braces:

MyClass {
    var <trivialGetter, >trivialSetter, <>trivialGetSet;
}

Hi Scott !

Thanks for your quick reply.

Yeah, I did write

myVar_{ |v| myVar = v }

My real question behind the scene was, when I have a lot of arguments, I need to “invent” variables names that are different from the instance variables names, and I was wondering if I could use this to differentiate instance variables and the function parameters.

For instance, if I have this class

Soup {
    var numberOfCarots;
    var numberOfPotatoes;
    var numberOfOnions;

    cook { |numberOfCarots, numberOfPotatoes, numberOfOnions|
        this.numberOfCarots = numberOfCarots;
        this.numberOfPotatoes = numberOfPotatoes;
        this.numberOfOnions = numberOfOnions;
        this.boil();
    }

    boil {
        // use numberOfCarots, numberOfPotatoes and numberOfOnions instance variables
    }
}

I don’t want numberOfCarots, numberOfPotatoes and numberOfOnions to be visible outside of the class.

In such a case,

s = Soup.new;
s.cook(1,2,3);

returns an error, which I understand, and I would have liked to know if I could have used this in that context, or another keyword.

To solve my problem here, I have to change the name of the parameters to cook.
Something like


Soup {
    var numberOfCarots;
    var numberOfPotatoes;
    var numberOfOnions;

    cook { |numberOfCarots1, numberOfPotatoes1, numberOfOnions1|
        numberOfCarots = numberOfCarots1;
        numberOfPotatoes = numberOfPotatoes1;
        numberOfOnions = numberOfOnions1;
        this.boil();
    }

    boil {
        // use numberOfCarots, numberOfPotatoes and numberOfOnions instance variables
    }
}

which I found was quite ugly.

This is not a big problem, just a question :wink: