puts
のように、関数のように見えるものもメソッドであるRubyに関数はないと思われると思いますが、Rubyには様々な関数があります。
メソッド
定義
定義
def method(argument, &block)
end
仮引数の直前に&
があると、このメソッドに渡されているブロックがProcのオブジェクトとしてこの引数に格納されます。
def block_class(&block)
block.class
end
irb> block_class {}
=> Proc
Ruby 3.1では、&
を渡すことで、ブロックを他のメソッドに渡せます。
def method(&)
def another(&)
end
end
一行メソッド定義
Ruby 3から使えます。
def square(x) = x * x
動的な定義
以下をメソッドにします。
- Method
- UnboundMethod
- ブロック
- Proc
def foo
end
define_method(:bar, method(:foo))
呼び出し
Rubyは()
を省略できます。
method() {}
method {}
オブジェクトをブロックの代わりに渡す
to_procメソッドが定義されたオブジェクトの前に&
をつけてメソッドに渡すと、そのメソッドが呼び出されるときにto_procが呼び出されます。
class Foo
def to_proc
proc do |item|
p item
end
end
end
irb> [1, 2, 3].each(&Foo.new)
=> [1, 2, 3]
ブロック
ブロックはメソッドに渡す無名関数です。
定義
do
とend
または{
と}
に囲まれた式をメソッドに渡します。
呼び出し
仮引数を使って呼び出す場合はProcの呼び出しと同じです。
def foo
yield(1, 2)
end
foo { |a, b| [a, b] }
Proc
Procは二種類あります。
- Proc
- lambda
Procとlambdaの違い
引数の扱い
lambdaのほうがより厳密です。引数の数が違っているとエラーになります。
irb> proc { |a, b, c| p a, b, c }.call(2, 4)
=> [2, 4, nil]
定義
Proc
Proc.new {}
proc {}
lambda
lambda {}
->() {}
呼び出し
.()
と::()
はcallメソッドの糖衣構文です。
fibonacci = lambda do |number|
case number
in 0 then 0
in 1 then 1
else
fibonacci.call(number - 2) + fibonacci.call(number - 1)
end
end
fibonacci[10]
fibonacci.call(10)
fibonacci.(10)
fibonacci::(10)
fibonacci === 10
fibonacci.yield(10)
Method
Methodはメソッドをオブジェクト化したものです。
生成
Object#methodによりオブジェクト化します。UnboundMethod#bindでUnboundMethodをレシーバにバインドします。
class Foo
def foo
end
end
Foo.new.method(:foo)
Foo.instance_method(:foo).bind(Foo.new)
呼び出し
呼び出しはProcの呼び出しと同じです。
UnboundMethod
レシーバを持たないメソッドを表すクラスです。
生成
Module#instance_methodやMethod#unbindで生成します。
class Foo
def foo
end
end
Foo.instance_method(:foo)
Foo.new.method(:foo).unbind
呼び出し
呼び出す前にbindする必要があります。
お詫び
投稿が遅くなりすみませんでした。