如何创建一个完全懒惰的opbjet?我有一个块,我想传递(作为依赖)"当前值" (在调用时),而不是依赖注入时的值。
我实际上无法传递lambda,因为所有服务都需要一个实际的对象,所以他们不会发送:call
给他们,只是访问它们。
这个(过于简化的)示例可能会澄清情况:
class Timer
def initialize(current_time)
@current_time = current_time
end
def print_current_time
print @current_time
end
end
class Injector
def current_time
# a lazy object that when accessed actually calls the lambda below
# every single time.
end
def current_time_lazy
-> { Time.now }
end
def instantiate(class_name)
# search for the class, look at the constructor and
# create an instance with the dependencies injected by
# name
# but to be simple
if class_name == "Timer"
Timer.new(current_time)
end
end
end
timer = Injector.new.instantiate("Timer")
timer.print_current_time # => some time
sleep 2
timer.print_current_time # => some *different* time
实际情况意味着绕过current_user
,但根据情况,当前用户可能会在注入这些值后更改。
我真的很感激任何建议(即使现在我会仔细排序依赖注入代码,所以这不会发生,但我认为它非常脆弱)
答案 0 :(得分:0)
这应该有所帮助:
class Timer
def initialize(current_time)
@current_time = current_time
end
def print_current_time
puts @current_time
end
end
class LazyMaker < BasicObject
def self.instantiate(class_name, lambada)
if class_name == 'Timer'
::Timer.new(new(class_name, lambada))
end
end
def initialize(class_name, lambada)
@lambada = lambada
end
def method_missing(method, *args)
@lambada.call.send(method, *args)
end
end
timer = LazyMaker.instantiate('Timer', -> { Time.now })
timer.print_current_time # some time
sleep 2
timer.print_current_time # some other time
我正在尝试使用委托来实现它,这样我就可以先调用该块,获取一个新对象并将方法调用重定向到它。为什么这样?因为基本上,访问一个对象来做某事意味着在它上面调用一个方法。例如,在print @current_time
中,它会发送@current_time.to_s
。
但由于几乎所有对象都有一些从Ruby中的标准基类继承的方法,如Object
,LazyMaker
也有类似to_s
的方法。所以我想从LazyMaker
继承BasicObject
继承,这是一个空白类。所以几乎所有的方法都被委派了。
但是,可能有另一种方法可以做到这一点。