Lets say I have the following:
class MyClass
class << self
def call(req_id)
@request_id = req_id
method_1
method_2
end
def method_1
puts "method 1 - req id: #{@request_id}"
sleep(@request_id)
end
def method_2
puts "method 2 - req id: #{@request_id}"
end
end
end
def func3
MyClass.call(6)
end
def func4
MyClass.call(2)
end
t1 = Thread.new{func3()}
sleep(1)
t2 = Thread.new{func4()}
t1.join
t2.join
And this produces the following output:
method 1 - req id: 6
method 1 - req id: 2
method 2 - req id: 2
method 2 - req id: 2
This makes sense since the class instance variable request_id
gets changed by func4
. But is there a way that we can make request_id
specific only to it's own thread such that we get the following result:
method 1 - req id: 6
method 1 - req id: 2
method 2 - req id: 2
method 2 - req id: 6
I can accomplish this by straight up passing req_id
to func3
and func4
but would like to avoid that if possible.
Is this possible to do by using instance vars?
CodePudding user response:
You can use instance methods
Just create instances in class method
Like this as idea
class MyClass
class << self
def call(req_id)
new(req_id).call
end
end
def call
method1
method2
end
private
def initialize(req_id)
@request_id = req_id
end
def method1
puts "method 1 - req id: #{@request_id}"
sleep(@request_id)
end
def method2
puts "method 2 - req id: #{@request_id}"
end
end
def func3
MyClass.call(6)
end
def func4
MyClass.call(2)
end
t1 = Thread.new { func3 }
sleep(1)
t2 = Thread.new { func4 }
t1.join
t2.join
# will print
method 1 - req id: 6
method 1 - req id: 2
method 2 - req id: 2
method 2 - req id: 6
CodePudding user response:
Only with dirty tricks: You could create the variable, and it will then be visible to the methods you are calling, but before you return from your "root" method, you have to destroy the variable again (using remove_instance_variable
), lest it would continue to exist for the lifetime of this object.
For the same reason, you have to be careful with exceptions. Therefore I would place the remove_instance_variable
into an ensure
clause, to make sure that it is executed even if the method is left prematurely by an exception.
However it may be better tor rethink your design. Instead of creating and destroying instance variables on the fly, consider creating them in the constructor and set them to nil
initially. Instead of removing the variable, set it to nil
again.