Meta


![](https://ruby.tw/logo.gif)

## ミミックメソッド
* a

```

```
## nilガード
* a

```

```
## 自己yield
* a

```

```
## Symbol#to_proc
* a

```

```
## 内部DSL
* a

```

```
## 外部DSL
* a

```

```

## Around alias
* 再定義したメソッドから以前のメソッドをエイリアスで呼び出す

```
class String
	alias_method :old_reverse, :reverse
	
	def reverse
		"x#{old_reverse}x"
	end
end

"abc".reverse " "xcbax"
```

## Blank slate
* オブジェクトからメソッドを削除して全てゴーストメソッドにする

```
class C
	def method_missing(name, *args)
		"ghost method"
	end
end

obj = C.new
obj.to_s # "#<C:0x007fbb2a10d2f8>"

class D < BasicObject
	def method_missing(name, *args)
		"ghost method"
	end
end

blank_slate = D.new
blank_slate.to_s # "ghost method"
```

## Class extension
* クラスの特異クラスにモジュールをインクルードして、クラスメソッドを定義する

```
class C; end

module M
	def my_method
		"class method"
	end
end

class << C
	include M
end

C.my_method # "class method"
```

## Class instance variable
* クラスの状態をClassオブジェクトのインスタンス変数に格納する

```
class C
	@my_class_instance_variable = "something"
	
	def self.class_attribute
		@my_class_instance_variable
	end
end

C.class_attribute # "something"
```

## Class macro
* クラス定義の中でクラスメソッドを使う

```
class C; end

class << C
	def my_macro(arg)
		"my_macro(#{arg}) called"
	end
end

class C
	my_macro :x # "my_macro(x) called"
end
```

## Clean room
* ブロックを評価する環境としてオブジェクトを使う

```
class CleanRoom
	def a_useful_method(x)
		x * 2
	end
end

CleanRoom.new.instance_eval {a_useful_method(3)} # 6
```

## Code processor
* 外部ソースにあるコード文字列を処理する

```
File.readlines("a_file_containing_lines_of_ruby.txt").each do |line|
	puts "#{line.chomp} ==> #{eval(line)}"
end

# >> 1 + 1 ==> 2
# >> 3 * 2 ==> 6
# >> Math.log10(100) ==> 2.0
```

## Context probe
* オブジェクトのコンテキストにある情報にアクセスするためにブロックを実行する

```
class C
	def initialize
		@x = "privateインスタンス変数"
	end
end
obj = C.new
obj.instance_eval {@x} # "privateインスタンス変数"
```

## Deferred evaluation
* Procやlambdaにコードとコンテキストを保管して後で評価する

```
class C
	def store(&block)
		@my_code_capsule = block
	end
end

def execute
	@my_code_capsule.call
end

obj = C.new
obj.store {$X = 1}
$X = 0
obj.execute
$X # 1
```

## Dynamic dispatch
* 実行時に呼び出すメソッドを決める

```
method_to_call = :reverse
obj = "abc"
obj.send(method_to_call) # "cba"
```

## Dynamic method
* 実行時にメソッドの定義方法を決める

```
class C
end
C.alacc_eval do
	define_method :my_method do
		"dynamic method"
	end
end

obj = C.new
obj.my_method # "dynamic method"
```

## Dynamic proxy
* メソッド呼び出しを動的に他のオブジェクトに転送する

```
class MyDynamicProxy
	def initialize(target)
		@target = target
	end
	
	def method_missing(name,*args,&block)
		"result: #{@target.send(name,*args,&block)}"
	end
end

obj = MyDynamicProxy.new("a string")
obj.reverse # "result: gnirts a"
```

## Flat scope
* クロージャを使って2つのスコープで変数を共有する

```
class C
	def an_attribute
		@attr
	end
end

obj = C.new
a_variable = 100

# flat scope:
obj.instance_eval do
	@attr = a_variable
end

obj.an_attribute # 100
```

## Ghost method
* 該当するメソッドのないメッセージに応答する

```
class C
	def method_missing(name, *args)
		name.to_s.reverse
	end
end

obj = C.new
obj.my_ghost_method # "dohtem_tsohg_ym"
```

## Hook method
* メソッドをオーバーライドして、オブジェクトモデルのイベントを捕まえる

```
$INHERITORS = []
class C
	def self.inherited(subclass)
		$INHERITORS << subclass
	end
end

class D << C
end

class E << C
end

class F << C
end

$INHERITORS # [D,E,F]
```

## Kernal method
* 全てのオブジェクトで使えるようにKernelモジュールにメソッドを定義する

```
module Kernal
	def a_method
		"kernel method"
	end
end

a_method # "kernel method"
```

## Lazy instance variable
* 最初にアクセスされるまでインスタンス変数を初期化しない

```
class C
	def attribute
		@attribute = @attribute || "something"
	end
end
obj = C.new
obj.attribute # "something"
```

## Mimic method
* 他の言語要素に偽装したメソッド

```
def BaseClass(name)
	name == "string" ? String : Object
end

class C < BaseClass "string" # クラスのように見えるメソッド
	attr_accessor :an_attribute # キーワードのように見えるメソッド
end

obj = C.new
onj.an_attribute = 1 # アトリビュートのように見えるメソッド
```

## Monkeypatch
* 既存のクラスの振る舞いを変更する

```
"abc".reverse # "cba"
class String
	def reverse
		"override"
	end
end

"abc".reverse # "override"
```

## Namespace
* 定数をモジュール内に定義して名前の衝突を防ぐ

```
module MyNamespace
	class Array
		def to_s
			"my class"
		end
	end
end
Array.new # []
MyNamespace::Array.new # "my class"
```

## nil guard
* nilへの参照をOR演算子で置き換える

```
x = nil
y = x || "something" # "something"
```

## object extention
* オブジェクトの特異クラスにモジュールをインクルードして特異メソッドを定義する

```
obj = Object.new
module M
	def my_method
		"特異メソッド"
	end
end

class << obj
	include M
end

obj.my_method # "特異メソッド"
```

## Open class
* 既存のクラスを修正

```
class String
	def my_string_method
		"my method"
	end
end
"abc".my_string_method # "my method"
```

## Prepend wrapper
* プリペンドした側からメソッドを呼び出す

```
mosule M
	def reverse
		"x#{super}x"
	end
end

String.class_eval do
	prepend M
end

"abc".reverse # "xcbax"
```

## Refinements
* クラスにパッチを当てる、モジュールのインクルードが有効な範囲、ファイルの終わりまで

```
module Myrefinements
	refine String do
		def reverse
			"my reverse"
		end
	end
end
"abc".reverse # "cba"
using MyRefinements
"abc".reverse # "my reverse"
```

## Refinements wrapper
* Refinementsした方からRefinementsしてないメソッドを呼び出す

```
module StringRefinements
	refine String do
		def reverse
			"x#{super}x"
		end
	end
end

using StringRefinements
"abc".reverse # "xcbax"
```

## Sandbox
* 信頼できないコードを安全な場所で実行する

```
def sandbox(&code)
	proc {
		$SAFE = 2
		yield
	}.call
	begin
		sandbox{File.delete 'a_file'}
	rescure Exeption => ex
		ex # <Security error: Insecure operation at level 2>
	end
end
```

## Scope gate
* class,module,defでスコープを区切る

```
a = 1
defined? a # "local-valiable"

moudle MyModule
	b = 1
	defined? a # nil
	defined? b # "local-variable"
end

defined? a # "local-variable"
defined? b # nil
```

## Self yield
* ブロックにselfを渡す

```
class Person
	attr_accessor :name, :surname
	def initialize
		yield self
	end
end

joe = Person.new do |p|
	p.name = "Joe"
	p.surname = "Smith"
end
```

## Shared scope
* 同じフラットスコープの複数のコンテキストで変数を共有する

```
lambda {
	shared = 10
	self.class.class_eval do
		define_method :counter do
			shared
		end
		define_method :down do
			shared -= 1
		end
	end
}.call

counter # 10
3.times {down}
counter # 7
```

## Singleton method
* 特定のオブジェクトにメソッドを定義する

```
obj = "abc"
class << obj
	def my_singleton_method
		"x"
	end
end
obj.my_singleton_method #"x"
```

## String of code
* 文字列を評価

```
my_string_of_code = "1+1"
eval(my_string_of_code) #2
```

## Symbol to proc
* メソッドを呼び出すブロックにシンボルを変換する

`[1,2,3,4].map(&:even?) #[false,true,false,true]`