我可以将字符串转换为带有Rails的类吗?

时间:2017-12-22 18:57:18

标签: ruby-on-rails ruby metaprogramming

想象一下,你有很多类可以访问你需要做的事情

ModuleA::ModuleB::ActualClassName

我想要的是绕过ModuleA::ModuleB部分,只需输入ActualClassName,让它知道我在说什么。

文件上有1:1的类,所以我使用Dir导航到目录并创建一个我想转换为变量的字符串类名数组。

TL;博士

给定["ClassOne", "ClassTwo"]使其成为

ClassOne == ModuleA::ModuleB::ClassOneClassTwo == ModuleA::ModuleB::ClassTwo

这个的基本目标是让我的生活更轻松在Rails控制台上。

编辑:我发现我真正要求的内容存在很多混乱,部分原因是我自己滥用了Ruby术语。相反,我会提出一个"填空#34;类型解决方案。

假设ModuleA::ModuleB::ClassOneModuleA::ModuleB::ClassTwo是定义的类

classes = ["ClassOne", "ClassTwo"]
# insert ruby magic here
ClassOne == ModuleA::ModuleB::ClassOne # true
ClassTwo == ModuleA::ModuleB::ClassTwo # true

4 个答案:

答案 0 :(得分:3)

classes = ['ClassOne', 'ClassTwo']

classes.each {|klass| Object.const_set(klass, ModuleA::ModuleB.const_get(klass))}

puts ClassOne == ModuleA::ModuleB::ClassOne # => true
puts ClassTwo == ModuleA::ModuleB::ClassTwo # => true

这不是您正在寻找的吗?参考:Module#const_getModulet#const_set

答案 1 :(得分:2)

回答你在问题标题中提出的问题(“我可以将字符串转换为局部变量”),

a = "hello"
thing_i_care_about = "a"
send(thing_i_care_about) # "hello"

但是,回答你在问题正文中提出的问题(需要ActiveSupport,它包含在Rails中)

mod_string = "ModuleA::ModuleB::"
klass = "ClassOne"
mod = "#{mod_string}#{klass}".safe_constantize 
如果引发错误,

String#safe_constantize将返回nil。

https://apidock.com/rails/String/safe_constantize

答案 2 :(得分:1)

您可以使用SELECT FirstName, LastName, FacultyID, HighestPaid FROM Teachers t CROSS APPLY (SELECT TOP 1 FirstName AS HighestPaid FROM Teachers WHERE FacultyID = t.FacultyID ORDER BY Salary DESC) ca

Object.const_get

如您所见,我创建了一个类,将其名称存储在变量中,并使用变量创建该类的新对象。当您想要更改给定类的实现时,这非常方便。

答案 3 :(得分:1)

您可以使用适当命名的Module#const_get方法获取常量的值,并使用名称相同的Module#const_set方法设置它:

classes.each |klass| do
  Object.const_set(klass, ModuleA::ModuleB.const_get(klass))
end