我想使用哈希来实例化某种类型的对象,但是问题很快就会出现,因为哈希只会实例化一个实例,然后永远会指向'那个例子。
class Person
end
factory = { "make_person" => Person.new }
a = factory["make_person"]
b = factory["make_person"]
a == b
=> true
即使哈希指向一个方法,例如make_person
,它调用它内部Person.new
,它仍将永远指向一个实例。
有人有解决方法吗?非常感谢。
答案 0 :(得分:4)
正在将对象( /**
* @Route("/logout")
*/
public function logoutAction() {
$this->get('security.token_storage')->setToken(null);
$this->get('request')->getSession()->invalidate();
//if this works how do I redirect to another route,
//specifically back to /login
return $this->render(
//do i need a template?
//do i need the array here?
);
}
的实例)分配给" make_person"键。
每当您要求Person
键时,您都会获得该对象。
您需要使用lambda初始化"make_person"
懒惰。
Person
答案 1 :(得分:2)
正确答案是哈希是错误的用法。
为什么不使用普通的Ruby类?
class Factory
def self.[](type)
case type
when "make_person"
Person.new
when "make_other_thing"
# ...
end
end
end
a = Factory["make_person"]
b = Factory["make_person"]
a == b # => false
如果你想得到一点点发烧友:
class Factory
class << self
def [](type)
return send(type) if respond_to?(type)
raise "I don't know how to do `#{type}'!"
end
def make_person
Person.new
end
def make_other_thing
# ...
end
end
end
...但是你可以调用Factory.make_person
,因此[]
方法似乎是多余的。
如果你真的,真的想要使用Hash来获取没有理由使用Hash的东西,你可以这样做:
factory = {
"make_person" => -> { Person.new }
}
a = factory["make_person"][]
b = factory["make_person"][]
a == b # => false
或者这个:
factory = Hash.new do |_, key|
case key
when "make_person"
Person.new
when "make_other_thing"
# ...
end
}
a = factory["make_person"]
b = factory["make_person"]
a == b # => false
答案 2 :(得分:0)
您引用了Person
的同一个实例,而不是Person
的一些新实例。
让我们挖掘一下:
[3] pry(main)> factory = {}
=> {}
[4] pry(main)> factory.object_id
=> 70344866826960
[5] pry(main)> class Person
[5] pry(main)* end
=> nil
[6] pry(main)> factory["make_person"] = Person.new
=> #<Person:0x007ff4e4136038>
人被实例化,让我们检查它的object_id:
[7] pry(main)> factory["make_person"].object_id
=> 70344887611420
让我们将它分配给变量a:
[8] pry(main)> a = factory["make_person"]
=> #<Person:0x007ff4e4136038>
让我们将它分配给变量b:
[9] pry(main)> b = factory["make_person"]
=> #<Person:0x007ff4e4136038>
现在既是&amp; b指向object_id
所示的同一对象[10] pry(main)> a.object_id
=> 70344887611420
[11] pry(main)> b.object_id
=> 70344887611420
正如克里斯所指出的那样,有几种方法可以让你的行为得以实现,但上述内容对你来说非常重要。
每次拨打factory["make_person"]
时如何确保新人员实例化的示例:
factory["make_person"] = lambda { Person.new }.call
=> #<Person:0x007ff4e0fa6ba8>
答案 3 :(得分:0)
不知道为什么你希望它成为哈希。但如果你坚持,我们走了:
factory = Hash.new do |_, key|
blueprints = { "make_person" => Person }
blueprints[key].new
end
person_x = factory["make_person"]
person_y = factory["make_person"]
person_x.object_id == person_y.object_id # => false