Ruby on rails 我可以用Rails将字符串转换成类吗?

Ruby on rails 我可以用Rails将字符串转换成类吗?,ruby-on-rails,ruby,metaprogramming,Ruby On Rails,Ruby,Metaprogramming,假设您有一堆需要访问的类 ModuleA::ModuleB::ActualClassName 我想绕过ModuleA::ModuleB部分,键入ActualClassName,让它知道我在说什么 文件到类的比例为1:1,因此我使用Dir导航到目录,并创建一个字符串类名数组,我希望将其转换为变量 tl;博士 给定[“一类”、“二类”]使其 ClassOne==ModuleA::ModuleB::ClassOne和ClassTwo==ModuleA::ModuleB::ClassTwo 这样做的基

假设您有一堆需要访问的类

ModuleA::ModuleB::ActualClassName
我想绕过
ModuleA::ModuleB
部分,键入
ActualClassName
,让它知道我在说什么

文件到类的比例为1:1,因此我使用Dir导航到目录,并创建一个字符串类名数组,我希望将其转换为变量

tl;博士 给定
[“一类”、“二类”]
使其

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

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

编辑:我发现我真正想要的东西有很多困惑,部分原因是我自己误用了Ruby术语。相反,我将提出一种“填空”类型的解决方案

假设
ModuleA::ModuleB::ClassOne
ModuleA::ModuleB::ClassTwo
是已定义的类

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

您可以使用
Object.const\u get

$irb
2.4.1 :001 > class Foo; end; classname='Foo'; p Object.const_get(classname).new 
#<Foo:0x007fd91f0db790>
 => #<Foo:0x007fd91f0db790> 
$irb
2.4.1:001>Foo类;结束;classname='Foo';p Object.const_get(classname).new
#
=> # 

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

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

但是,要回答您在问题主体中提出的问题(需要ActiveSupport,它包含在Rails中)

String#safe_constantize
如果引发错误,将返回nil


这不是你要找的吗?Ref:,

您可以使用适当命名的方法获取常数的值,并使用同样命名的方法进行设置:


我很难看出这与局部变量有什么关系。这与将字符串转换为局部变量有什么关系?“将字符串转换为局部变量”意味着什么?这意味着我有一个字符串“ClassOne”,我想执行与ClassOne=ModuleA::ModuleB::ClassOne完全相同的ruby代码。除非它必须基于字符串,否则这是不可能的。局部变量名必须以小写字母开头,这就是它们成为局部变量的原因。但是,数组中的字符串以大写字母开头,因此,您想要的显然是不可能的。啊,好吧,那么我认为“局部变量”是错误的名称,也许“常量”更正确?如果您打开irb并说Abc=1,然后键入Abc,它返回1,因此在某些级别上,Abc现在是一个命名变量。也许我的行话不像ruby那么具体,但从概念上来说这是不可能的吗?也许问题不像我想的那么清楚。我试图获取一个字符串数组,并使其成为一个局部变量名,表示嵌套在模块中的类。这是不可能的。局部变量名必须以小写字母开头,这就是它们成为局部变量的原因。但是,数组中的字符串以大写字母开头,因此,您想要的显然是不可能的。我对原始问题进行了编辑,添加了更多内容clarification@nick,编辑了我的答案。对不起,我一直在度假,这正是我想要的。谢谢你,新年快乐!我的荣幸@nick,也祝你新年快乐!如果这个或任何答案已经解决了你的问题,请考虑点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这么做。我试图在几个模块中嵌套类Foo时实现这一点,这样在rails控制台的顶层,我就可以使用Foo访问ModuleA::ModuleB::Foo
a = "hello"
thing_i_care_about = "a"
send(thing_i_care_about) # "hello"
mod_string = "ModuleA::ModuleB::"
klass = "ClassOne"
mod = "#{mod_string}#{klass}".safe_constantize 
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
classes.each |klass| do
  Object.const_set(klass, ModuleA::ModuleB.const_get(klass))
end