Rubyメタプログラミング小結
3778 ワード
今日このような質問をされて、以前はいつもこれが比較的に広い概念だと思っていましたが、自分がこれらの特性を使ったことがあっても、これを「メタプログラミング」と呼ぶことを知らなかったので、今日人に聞かれたとき、やっと悟って、それからネット上で自分の平実用的なメタプログラミングとまとめました.
従来のRubyにおけるメタプログラミングとは,実行時に動的に言語構造(クラス,モジュール,インスタンス変数など)を操作できる技術である.再起動せずに、実行時に新しいRubyコードを直接入力して実行することもできます.
Rubyのメタプログラミングは、「コードを利用してコードを書く」という役割もあります.たとえば、一般的なattr_アクセスなどの方法はそうです.まず私が考えられるのは、自分が使ったことのいくつかです.
1,respond_to? 2,define_method 3,instance_variable_get, instance_variable_set 4,evalでもこの方法はできるだけ避けることができて、実行効率は特に低いです!!
具体的な意味は、方法の名前を見ると、これらの方法の実現する論理がわかるに違いない.具体的には詳しく見ることができるhttp://api.rubyonrails.org/ソースコードを具体的に分析するのは簡単です.以下は私が他の場所から検索して、今後の仕事の中で自分のプログラミングスキルを高めるのに役立つようにします.1、内省、反射
Rubyでは、実行時にクラスまたはオブジェクトの情報を表示する能力があります.class、instanceを使用できます.methods、 intance_variablesなどの方法で目的を達成します.この技術は内省(Introspection)または反射(Reflection)になると述べた.
メタプログラムを記述する言語をメタ言語と呼ぶ.操作されるプログラムの言語をターゲット言語と呼ぶ.一つのプログラミング言語は同時に自身のメタ言語である能力を反射あるいは自反と呼ぶ.――ウィキペディアのプログラミング項目から抜粋します.
respond_to?方法は反射機構におけるもう一つの有用な方法である.respond_の使用to?方法は、オブジェクトが実行したい情報を処理できるかどうかを事前に知ることができます.すべてのオブジェクトにこのメソッドがあり、respond_を使用します.to?メソッドを使用すると、オブジェクトが指定したメソッドを使用できるかどうかを決定できます.
2,instance_eval Objectクラスにはinstance_という名前のクラスがあります.evalの公開メソッド.このメソッドは、インスタンスによって呼び出され得る.彼はオブジェクトのインスタンス変数を操作する方法を提供した.文字列を使用してパラメータを渡すか、コードブロックを渡すことができます.
instanceで_evalが渡すコードブロックは、オブジェクト内で操作できるようにします.オブジェクトの内部で勝手に操作することができ、プライベートなデータはもうありません.instance_evalは、クラスメソッドを追加するためにも使用できます.
似たような、const_getとconst_setは定数を操作するために使用されます.const_getは、指定した定数の値を返します.
const_set指定した定数に指定した値を設定し、そのオブジェクトを返します.定数が存在しない場合は、次のように定数を作成します.
なぜならconst_getは定数の値を返すので、このメソッドを使用してクラスの名前を取得し、このクラスに新しいインスタンス化オブジェクトを追加する方法があります.これにより、実行時にクラスを作成し、インスタンス化することができます.
従来のRubyにおけるメタプログラミングとは,実行時に動的に言語構造(クラス,モジュール,インスタンス変数など)を操作できる技術である.再起動せずに、実行時に新しいRubyコードを直接入力して実行することもできます.
Rubyのメタプログラミングは、「コードを利用してコードを書く」という役割もあります.たとえば、一般的なattr_アクセスなどの方法はそうです.まず私が考えられるのは、自分が使ったことのいくつかです.
1,respond_to? 2,define_method 3,instance_variable_get, instance_variable_set 4,evalでもこの方法はできるだけ避けることができて、実行効率は特に低いです!!
具体的な意味は、方法の名前を見ると、これらの方法の実現する論理がわかるに違いない.具体的には詳しく見ることができるhttp://api.rubyonrails.org/ソースコードを具体的に分析するのは簡単です.以下は私が他の場所から検索して、今後の仕事の中で自分のプログラミングスキルを高めるのに役立つようにします.1、内省、反射
Rubyでは、実行時にクラスまたはオブジェクトの情報を表示する能力があります.class、instanceを使用できます.methods、 intance_variablesなどの方法で目的を達成します.この技術は内省(Introspection)または反射(Reflection)になると述べた.
メタプログラムを記述する言語をメタ言語と呼ぶ.操作されるプログラムの言語をターゲット言語と呼ぶ.一つのプログラミング言語は同時に自身のメタ言語である能力を反射あるいは自反と呼ぶ.――ウィキペディアのプログラミング項目から抜粋します.
classRubyist
defwhat_does_he_do
@person='A Rubyist'
'Ruby programming'
end
end
an_object = Rubyist.new
puts an_object.class# => Rubyist
puts an_object.class.instance_methods(false)# => what_does_he_do
an_object.what_does_he_do
puts an_object.instance_variables# => @person
respond_to?方法は反射機構におけるもう一つの有用な方法である.respond_の使用to?方法は、オブジェクトが実行したい情報を処理できるかどうかを事前に知ることができます.すべてのオブジェクトにこのメソッドがあり、respond_を使用します.to?メソッドを使用すると、オブジェクトが指定したメソッドを使用できるかどうかを決定できます.
2,instance_eval Objectクラスにはinstance_という名前のクラスがあります.evalの公開メソッド.このメソッドは、インスタンスによって呼び出され得る.彼はオブジェクトのインスタンス変数を操作する方法を提供した.文字列を使用してパラメータを渡すか、コードブロックを渡すことができます.
classRubyist
definitialize
@geek="Matz"
end
end
obj = Rubyist.new
# instance_eval obj
obj.instance_evaldo
putsself# => #puts@geek# => Matz
end
instanceで_evalが渡すコードブロックは、オブジェクト内で操作できるようにします.オブジェクトの内部で勝手に操作することができ、プライベートなデータはもうありません.instance_evalは、クラスメソッドを追加するためにも使用できます.
classRubyist
end
Rubyist.instance_evaldo
defwho
"Geek"
end
end
puts Rubyist.who# => Geek
const_get, const_set
似たような、const_getとconst_setは定数を操作するために使用されます.const_getは、指定した定数の値を返します.
puts Float.const_get(:MIN)# => 2.2250738585072e-308
const_set指定した定数に指定した値を設定し、そのオブジェクトを返します.定数が存在しない場合は、次のように定数を作成します.
classRubyist
end
puts Rubyist.const_set("PI",22.0/7.0)# => 3.14285714285714
なぜならconst_getは定数の値を返すので、このメソッドを使用してクラスの名前を取得し、このクラスに新しいインスタンス化オブジェクトを追加する方法があります.これにより、実行時にクラスを作成し、インスタンス化することができます.
# Let us call our new class 'Rubyist'
# (we could have prompted the user for a class name)
class_name ="rubyist".capitalize
Object.const_set(class_name,Class.new)
# Let us create a method 'who'
# (we could have prompted the user for a method name)
class_name =Object.const_get(class_name)
puts class_name# => Rubyist
class_name.class_evaldo
define_method:whodo|my_arg|
my_arg
end
end
obj = class_name.new
puts obj.who('Matz')# => Matz