[解決済み] Rubyでリフレクション?
質問
この仕組みが気になります。例えば、ファクトリーパターンに基づいたクラスを作成し、後で使用するクラスを登録し、次のようなことを行うとします。
FactoryClass.register('YourClassName', [param, param, ...]);
FactoryClass.create('your_class_name').call_method_from_this_object
ここで
'class_name'
は値にマップされるハッシュのキーです。
ClassName
のようなものはありますか? phpリフレクション 文字列名に基づいてクラスのインスタンスを作成し、引数を渡すことができるのでしょうか?(phpでは、引数はそれらの配列になり、phpはそれをどのように扱うか知っています)
では、実際の例を挙げてみると。
class Foo
attr_reader :something
def initialize(input)
@something = input
end
def get_something
return @something
end
end
# In the factory class, foo is then placed in a hash: {'foo' => 'Foo'}
# This step might not be required??
FactoryClass.create('Foo', ['hello'])
# Some where in your code:
FactoryClass.create('foo').get_something # => hello
これはrubyで可能なのでしょうか?しかし、このような文字列名からクラスインスタンスを作成し、オブジェクトを渡すためのAPIやドキュメントを見たことがありません。
上のハッシュについては、今考えると、おそらく次のようなことをしなければならないでしょう。
{'foo' => {'class' => 'Foo', 'params' => [param, param, ...]}}
この方法では
.create
の上で
FactoryClass
をインスタンス化することができます。
Foo
を、関連するパラメータと一緒に指定します。
もし、私の考えが大きく外れていたら、遠慮なくご教示ください。
解決方法は?
を使用しない回答があります。
eval
.
PHPの
Reflection
というのは
Metaprogramming
というように、Rubyとは全く異なるものです。Rubyではすべてがオープンで、アクセスすることができる。
次のようなコードを考えてみましょう。
class Foo
attr_reader :something
def initialize(input)
@something = input
end
def get_something
return @something
end
end
@registered = { }
def register(reference_name, class_name, params=[])
@registered[reference_name] = { class_name: class_name, params: [params].flatten }
end
def create(reference_name)
h = @registered[reference_name]
Object.const_get(h[:class_name]).new(*(h[:params]))
end
register('foo', 'Foo', ['something'])
puts create('foo').get_something
を使用することができます。
Object#const_get
を使って、文字列からオブジェクトを取得することができます。
Object.const_get('Foo')
はオブジェクトを与えます。
Foo
.
しかし、クラス名を文字列で送る必要はありません。クラス名をオブジェクトとして渡し、それを直接使用することもできます。
class Foo
attr_reader :something
def initialize(input)
@something = input
end
def get_something
return @something
end
end
@registered = { }
def register(reference_name, class_name, params=[])
@registered[reference_name] = { class_name: class_name, params: [params].flatten }
end
def create(reference_name)
h = @registered[reference_name]
h[:class_name].new(*(h[:params]))
end
register('foo', Foo, ['something else'])
puts create('foo').get_something
関連
-
[解決済み】Ruby: 特定のバージョンのruby gemをインストールする方法は?
-
[解決済み] Rubyのswitch文の書き方
-
[解決済み] Rubyで配列に値が存在するかどうかを確認する方法
-
[解決済み] Rubyからシェルコマンドを呼び出す方法
-
[解決済み] Rubyでnilとemptyとblankを理解する方法
-
[解決済み] Rubyで文字列を小文字・大文字に変換する方法
-
[解決済み] Rubyのattr_accessorとは何ですか?
-
[解決済み] Ruby on Railsで現在の絶対URLを取得するにはどうすればよいですか?
-
[解決済み] Rubyのclass << selfイディオム
-
[解決済み] Rubyで「例外 => e」を救済するのはなぜ悪いスタイルなのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】macOSでrbenvをアンインストールする方法とは?
-
[解決済み】Ruby:kind_of? vs. instance_of? vs. is_a?
-
[解決済み] Aptana Studio 3.6をWindowsにインストールできない
-
[解決済み] RubyのHashをキーでアルファベット順にソートする方法
-
[解決済み] Rubyで日付文字列をパースする
-
[解決済み] マトリックスサムネーションチャレンジ
-
[解決済み] Ruby: 文字列をブーリアンに変換する方法
-
[解決済み] Rubyでリフレクション?
-
[解決済み] Rubyでファイルを移動するにはどうしたらいいですか?
-
[解決済み] Rubyで2次元配列の作成と反復処理