1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RubyAdvent Calendar 2021

Day 23

関数のまとめ

Last updated at Posted at 2021-12-25

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]

ブロック

ブロックはメソッドに渡す無名関数です。

定義

doendまたは{}に囲まれた式をメソッドに渡します。

呼び出し

仮引数を使って呼び出す場合はProcの呼び出しと同じです。

def foo
  yield(1, 2)
end
foo { |a, b| [a, b] }

Proc

Procは二種類あります。

  1. Proc
  2. 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する必要があります。

お詫び

投稿が遅くなりすみませんでした。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?