2017-12-22 7 views
2

はあなたが私が好きな何文字列をRailsでクラスに変換できますか?

ModuleA::ModuleB::ActualClassName 

を行う必要がアクセスするためのクラスの束を持っている想像しModuleA::ModuleB一部をバイパスして、ちょうどActualClassNameを入力し、それが話して何イム知っていることです。

私はDirを使用してディレクトリに移動し、変数に変換する文字列クラス名の配列を作成するために、クラスに対してファイルに1:1があります。

TL;これの基本的な目標は、Railsのコンソール上で私の人生を容易にすることである

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

よう["ClassOne", "ClassTwo"]与えられたDR

はそれを作ります。

EDIT:Rubyの用語を誤って使用しているために、私が本当に求めていることの周りに混乱があります。代わりに、私は「空欄で埋める」タイプのソリューションを提案します。

ModuleA::ModuleB::ClassOneModuleA::ModuleB::ClassTwo定義されているクラス

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

を、私は、これは持っているものを見てトラブルを抱えていますローカル変数と関連付ける –

+0

これは文字列をローカル変数に変換することと何が関係していますか?それは文字列をローカル変数に変換することを意味するのでしょうか? –

+0

これは、 "ClassOne"という文字列があり、ClassOne = ModuleA :: ModuleB :: ClassOneと同じことをするルビコードを実行したいことを意味します。文字列に基づいていなければなりません – nick

答えて

1

あなたはObject.const_getを使用できると仮定します。

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

あなたは、私は、クラスを作成し、変数にその名前を保存し、新しいを作成する見ることができるように変数を使ってそのクラスのオブジェクト。これは、あるクラスの実装を変更したいときに非常に便利です。

+0

クラスFooがいくつかのモジュール内でネストされているときに、これを達成しようとしています。例えば、レールコンソール内のトップレベルでModuleA :: ModuleB :: FooにFoo – nick

2

あなたが身体に尋ねる質問に答えるために、

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 

String#safe_constantize nilを返します(Railsのに含まれてactivesupportのは、必要となります)。

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

+0

を使ってアクセスできます。 私は文字列の配列をとって、各文字列がモジュール内でネストされているそのクラスを表すローカル変数名になるようにしようとしています – nick

+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

+0

いいえ私は手動でクラスをCとして定義する必要を避け、ルビメタプログラミングを使用して、モジュールスコープのクラス名を表す文字列の配列を反復処理し、トップレベルのクラス名として格納します。私はより明確にオリジナルの質問を編集しました – nick

+0

@nick、私の答えを編集しました。 – hallucinations

+0

申し訳ありません私は休暇を過ごしています、それはまさに私があなたと幸せな新年に感謝のために探していたものです! – nick

1

あなたは適切な名前のModule#const_get方法を使用して、一定の値を取得してもよく名前のModule#const_set方法使用して、それを設定することができます。

classes.each |klass| do 
    Object.const_set(klass, ModuleA::ModuleB.const_get(klass)) 
end 
関連する問題