Rubyメタプログラミング
4432 ワード
インスタンス変数(Instance Variables)は、それらを使用するときに作成されるオブジェクトです.したがって、同じクラスのインスタンスであっても、異なるインスタンス変数を持つことができる.
技術的には、1つのオブジェクト(インスタンス)は、そのインスタンス変数とその属するクラスの参照を格納するだけです.したがって、1つのオブジェクトのインスタンス変数はオブジェクトにのみ存在し、メソッド(インスタンスメソッド(Instance Methods)と呼ばれる)はオブジェクトが属するクラスに存在します.これは,同じクラスのインスタンスがクラス内のメソッドを共有しているのに,インスタンス変数を共有できない理由である.
クラス#クラス#
n = Class.new
puts n.ancestors
puts n.supperclass
puts n.supperclass.supperclass
puts n.supperclass.supperclass.supperclass
クラスを開く
実はこれは方法の再定義と同じ結果ですが、勝手に変更すると深刻な結果をもたらす可能性があります.例えば、あなたが変更したこの方法は他の場所で使用されているので、この方法は慎重に使用してください.この方法が他の結果をもたらさないことを明確にしない限り.
puts 'abc'.replace('a') # a
class String
def replace(string)
puts ' '
end
end
'abc'.replace('a') #' '
を用いてこのプロセスを実現することもできます細分化
module StringExtensions
refine String do
def replace(string)
puts ' '
end
end
end
この方法を使う必要がある場所でusingを使う
例えば、
using StringExtensions
の細分化のメリットは、グローバルな影響を及ぼさないことです.使用する必要がある場所でusingすればいいので、リスクは比較的小さいです.呼び出し方法
クラス内のメソッドはどのように呼び出されますか?
selfキーワード
いつでも、Rubyの中で現在のオブジェクトとして機能するオブジェクトは1つしかなく、このロールとして長く機能するオブジェクトはありません.メソッドを呼び出すと、受信者はselfになります.この瞬間から、すべてのインスタンス変数はselfのインスタンス変数であり、受信者を明確に指定していないすべてのメソッドはself上で呼び出されます.栗を挙げます.
class Book
def get_library
@book_count = 1000
self
end
def self.is_my_book?(book)
false
end
end
b = Book.new
b.get_library # ,b self
b.is_my_book?('Ruby ') # undefined method `is_book?' for #<0x00000002b92268> (NoMethodError)
Book.is_my_book?('Ruby ') # false
上からis_を呼び出しますmy_book?の方法はどうして間違っていますか?それは,
self.is_my_book?(book)
がBook.is_my_book?(book)
に等しいb呼び出し時にselfがbインスタンスオブジェクトを参照し,Bookに等しくないため,メソッドが見つからないエラーを投げ出すからである.方法
class Book
def create_book
'Ruby '
end
def update_book
'Ruby '
end
def delete_book
'Ruby '
end
def search_book
'Ruby '
end
end
s = Book.new
puts s.send(:get_one_name)
puts s.send(:get_two_name)
puts s.send(:get_three_name)
puts s.send(:get_four_name)
class Book
['create', 'update', 'delete', 'search'].each do |item|
define_method("#{item}_book"){
puts "#{item}-Ruby "
}
end
end
b = Book.new
b.create_book # create-Ruby
b.update_book # update-Ruby
b.delete_book # delete-Ruby
b.search_book # search-Ruby
# encoding: utf-8
class Book
def method_missing(name, *argc)
if [:create_book, :update_book, :delete_book, :search_book].include?(name)
puts "#{name}-Ruby "
else
super
end
end
end
b = Book.new
b.create_book# create-Ruby
b.update_book# update-Ruby
b.delete_book # delete-Ruby
b.search_book# search-Ruby
b.book # undefined method `book'
コードブロック
...
クラスマクロ
従来の方法では、属性の読み書きを定義するには、次のようなGetメソッドとSetメソッドを各属性に定義する必要があります.
class Post
def title=(title)
@title = title
end
def title
@title
end
....
....
文章のようにtitle,content,authorなどの属性を定義すると,3つのグループを書く必要があり,非常に不便である.このとき、Rubyのクラスマクロ
attr_accessor
(moduleのクラスの中の1つのC言語で書く方法、ハイパーリンクを添付して、以上のコードを書くことができます class Post
attr_accessor :title
end
Evalメソッド