Currently I'm developing a Watcher
class in Ruby, which, among other things, is able to find the period duration of a toggling signal. This is in general rather simple, but a problem I'm facing is that apparently Ruby passes all parameters by value.
While researching online I found many different discussions about what "pass by value" and "pass by reference" actually is, but no actual "how to". Coming from a C/C++ background, for me this is an essential part of a programming/scripting language.
The relevant parts of the class that I wrote are shown below. The method Watcher::watchToggling() is the one I'm having trouble with. As a parameter, aVariable
should be the reference to the value I'm measuring the period duration for.
class Watcher
@done
@timePeriod
def reset()
@done = false;
@timePeriod = nil;
end
def watchToggling(aVariable, aTimeout=nil)
oldState = aVariable;
oldTime = 0;
newTime = 0;
timeout(aTimeout)do
while(!@done)
newState = aVariable;
if(newState != oldState)
if(newState == 1)
# rising edge
if(oldTime != 0)
# there was already a rising edge before,
# so we can calculate the period
newTime = Time.now();
@timePeriod = newTime - oldTime;
@done = true;
else
# if there was no previous rising edge,
# set the time of this one
oldTime = Time.now();
end
end
oldState = newState;
end
end
end
puts("Watcher: done.")
end
def isDone()
return @done;
end
def getTimePeriod()
return @timePeriod;
end
end
Is there any way at all in ruby to pass by reference? And if not, are there alternatives that would solve this problem?
Ruby is strictly pass-by-value, which means references in the caller's scope are immutable. Obviously they are mutable within the scope, since you can assign to them after all, but they don't mutate the caller's scope.
Note, however, that the object can be mutated even if the reference cannot:
If the object you get passed is immutable, too, then there is nothing you can do. The only possibilities for mutation in Ruby are mutating the reference (by assignment) or asking an object to mutate itself (by calling methods on it).
You can return an updated value from your method and have the caller assign that to the reference:
Or you can wrap the immutable object in a mutable one and mutate that mutable wrapper:
[This is really the same thing as the second example above.]
But if you can't change anything, then you are stuck.