サーチ…


前書き

Rubyの関数は、一連のアクションを実行するための、組織化された再利用可能なコードを提供します。関数はコーディングプロセスを簡素化し、冗長ロジックを防止し、コードを簡単にフォローします。このトピックでは、Rubyにおける関数、引数、パラメータ、yield文、スコープの宣言と利用について説明します。

備考

メソッドとは、1つまたは複数のオブジェクトに関連付けられ、名前に加えてパラメータのリストによって一般的に識別される名前付きのコードブロックです。

def hello(name)
  "Hello, #{name}"
end

メソッド呼び出しは、メソッド名、呼び出されるオブジェクト(受信者とも呼ばれる)、および名前付きメソッドのパラメーターに割り当てられた0個以上の引数値を指定します。メソッドで評価された最後の式の値は、メソッド呼び出し式の値になります。

hello("World")
# => "Hello, World"

受信者が明示的でない場合、それはselfです。

self
# => main

self.hello("World")
# => "Hello, World"

Rubyプログラミング言語の書籍で説明されているように、多くの言語は、関連オブジェクトを持たない関数と、受信側オブジェクトで呼び出されるメソッドとを区別します。 Rubyは純粋にオブジェクト指向言語なので、すべてのメソッドは真のメソッドであり、少なくとも1つのオブジェクトに関連付けられています。

メソッドパラメータの概要

タイプメソッドシグネチャ呼び出しの例割り当て
Rは等しく def fn(a,b,c) fn(2,3,5) a=2, b=3, c=5
Vアリアドック def fn(*rest) fn(2,3,5) rest=[2, 3, 5]
D efault def fn(a=0,b=1) fn(2,3) a=2, b=3
K eyword def fn(a:0,b:1) fn(a:2,b:3) a=2, b=3

これらの引数型は、バリデーショナル関数を作成するために想像できるどんな方法でも組み合わせることができます。関数への引数の最小数は、署名に必要な引数の量と等しくなります。余分な引数は、デフォルトのパラメータに割り当てられ、次に*restパラメータに割り当てられます。

タイプメソッドシグネチャ呼び出しの例割り当て
R、D、V、R def fn(a,b=1,*mid,z) fn(2,97) a=2, b=1, mid=[], z=97
fn(2,3,97) a=2, b=3, mid=[], z=97
fn(2,3,5,97) a=2, b=3, mid=[5], z=97
fn(2,3,5,7,97) a=2, b=3, mid=[5,7], z=97
R、K、K def fn(a,g:6,h:7) fn(2) a=2, g=6, h=7
fn(2,h:19) a=2, g=6, h=19
fn(2,g:17,h:19) a=2, g=17, h=19
VK def fn(**ks) fn(a:2,g:17,h:19) ks={a:2, g:17, h:19}
fn(four:4,five:5) ks={four:4, five:5}

1つの必須パラメータ

def say_hello_to(name)
    puts "Hello #{name}"
end

say_hello_to('Charles')    # Hello Charles

複数の必須パラメータ

def greet(greeting, name)
    puts "#{greeting} #{name}"
end

greet('Hi', 'Sophie')    # Hi Sophie

デフォルトパラメータ

def make_animal_sound(sound = 'Cuack')
    puts sound
end

make_animal_sound('Mooo') # Mooo
make_animal_sound         # Cuack

複数の引数にデフォルトを含めることは可能です:

def make_animal_sound(sound = 'Cuack', volume = 11)
    play_sound(sound, volume)
end

make_animal_sound('Mooo') # Spinal Tap cow

しかし、最初のものも供給せずに2番目のもの供給することはできません。位置パラメータを使用する代わりに、キーワードパラメータを試してください:

def make_animal_sound(sound: 'Cuack', volume: 11)
    play_sound(sound, volume)
end

make_animal_sound(volume: 1) # Duck whisper

または、オプションを格納するハッシュパラメータ:

def make_animal_sound(options = {})
    options[:sound]  ||= 'Cuak'
    options[:volume] ||= 11
    play_sound(sound, volume)
end

make_animal_sound(:sound => 'Mooo') 

デフォルトのパラメータ値は、任意のルビ表現で設定できます。式はメソッドのコンテキストで実行されるため、ここでローカル変数を宣言することもできます。注:コードレビューは行われません。 これ指摘するカイウスの礼儀。

def make_animal_sound( sound = ( raise 'TUU-too-TUU-too...' ) ); p sound; end

make_animal_sound 'blaaaa' # => 'blaaaa'
make_animal_sound          # => TUU-too-TUU-too... (RuntimeError)

オプションのパラメータ(スプラット演算子)

def welcome_guests(*guests)
    guests.each { |guest| puts "Welcome #{guest}!" }
end

welcome_guests('Tom')    # Welcome Tom!
welcome_guests('Rob', 'Sally', 'Lucas') # Welcome Rob!
                                        # Welcome Sally!
                                        # Welcome Lucas!

welcome_guests(['Rob', 'Sally', 'Lucas'])Welcome ["Rob", "Sally", "Lucas"]!
代わりに、もしあなたがリストを持っていれば、 welcome_guests(*['Rob', 'Sally', 'Lucas'])実行でき、 welcome_guests('Rob', 'Sally', 'Lucas')ます。

必要なデフォルトのオプションパラメータの組み合わせ

def my_mix(name,valid=true, *opt)
    puts name
    puts valid
    puts opt
end

次のように呼び出します。

my_mix('me')
# 'me'
# true
# []

my_mix('me', false)
# 'me'
# false
# []

my_mix('me', true, 5, 7) 
# 'me'
# true
# [5,7]

メソッド定義は式です

Ruby 2.xでメソッドを定義すると、その名前を表すシンボルが返されます:

class Example
  puts def hello
  end
end

#=> :hello

これは面白いメタプログラミング技術を可能にする。たとえば、メソッドは他のメソッドでラップすることができます。

class Class
  def logged(name)
    original_method = instance_method(name)
    define_method(name) do |*args|
      puts "Calling #{name} with #{args.inspect}."
      original_method.bind(self).call(*args)
      puts "Completed #{name}."
    end
  end
end

class Meal
  def initialize
    @food = []
  end
  
  logged def add(item)
    @food << item
  end
end

meal = Meal.new
meal.add "Coffee"
# Calling add with ["Coffee"].
# Completed add.

宣言されていないキーワード引数を取り込む(二重スプラット)

**演算子は*演算子と同様に動作しますが、キーワードパラメータに適用されます。

def options(required_key:, optional_key: nil, **other_options)
  other_options
end

options(required_key: 'Done!', foo: 'Foo!', bar: 'Bar!')
#> { :foo => "Foo!", :bar => "Bar!" }

上記の例では、 **other_optionsが使用されていない場合、 ArgumentError: unknown keyword: foo, bar errorが発生します。

def without_double_splat(required_key:, optional_key: nil)
  # do nothing
end

without_double_splat(required_key: 'Done!', foo: 'Foo!', bar: 'Bar!')
#> ArgumentError: unknown keywords: foo, bar

これは、メソッドに渡すオプションのハッシュがあり、キーをフィルタリングしたくない場合に便利です。

def options(required_key:, optional_key: nil, **other_options)
  other_options
end

my_hash = { required_key: true, foo: 'Foo!', bar: 'Bar!' }

options(my_hash)
#> { :foo => "Foo!", :bar => "Bar!" }

**演算子を使用してハッシュを解凍することもできます。これにより、他のハッシュの値に加えて、メソッドにキーワードを直接与えることができます:

my_hash = { foo: 'Foo!', bar: 'Bar!' }

options(required_key: true, **my_hash)
#> { :foo => "Foo!", :bar => "Bar!" }

ブロックへの降伏

あなたのメソッドにブロックを送ることができ、ブロックを複数回呼び出すことができます。これは、proc / lambdaなどを送信することによって行うことができますが、 yield上げるとより簡単で高速になります。

def simple(arg1,arg2)
  puts "First we are here:  #{arg1}"
  yield
  puts "Finally we are here:  #{arg2}"
  yield
end
simple('start','end') { puts "Now we are inside the yield" }

#> First we are here:  start
#> Now we are inside the yield
#> Finally we are here:  end
#> Now we are inside the yield

{ puts ... }はカッコの中にはなく、暗黙のうちに来ることに注意してください。これはまた、1つのyieldブロックしか持てないことを意味します。 yield引数を渡すことができます:

def simple(arg)
  puts "Before yield"
  yield(arg)
  puts "After yield"
end
simple('Dave') { |name| puts "My name is #{name}" }

#> Before yield
#> My name is Dave
#> After yield

yieldでは、イテレータや他のコードで動作する関数を簡単に作成できます。

def countdown(num)
  num.times do |i|
    yield(num-i)
  end
end

countdown(5) { |i| puts "Call number #{i}" }

#> Call number 5
#> Call number 4
#> Call number 3
#> Call number 2
#> Call number 1

実際、 foreacheach 、そしてtimesようなものは、一般的にクラスで実装されているというyieldがあります。

あなたがブロックを与えられているかどうかを知りたければ、 block_given?

class Employees
  def names
    ret = []
    @employees.each do |emp|
      if block_given?
        yield(emp.name)
      else
        ret.push(emp.name) 
      end
    end

    ret
  end
end

この例では、ことを前提としてEmployeesクラスが持つ@employeesで反復することができ、リストeach使用して従業員の名前持っているオブジェクトを取得するにはnameメソッドを。私たちはブロックを与えられている場合は、我々はよyield 、ブロックに名前をそう私達はちょうど私たちが返す配列にプッシュ。

タプルの引数

メソッドは配列パラメーターをとり、それを直ちに名前付きローカル変数に分解することができます。 Mathias Meyerのブログにあります。

def feed( amount, (animal, food) )

    p "#{amount} #{animal}s chew some #{food}"

end

feed 3, [ 'rabbit', 'grass' ] # => "3 rabbits chew some grass"

メソッドの定義

メソッドはdefキーワードで定義され、その後にメソッド名と括弧で囲まれたオプションのパラメータ名のリストが定義されます。 defend間のRubyコードはメソッドの本体を表します。

def hello(name)
  "Hello, #{name}"
end

メソッド呼び出しは、メソッド名、呼び出されるオブジェクト(受信者とも呼ばれる)、および名前付きメソッドのパラメーターに割り当てられた0個以上の引数値を指定します。

hello("World")
# => "Hello, World"

受信者が明示的でない場合、それはselfです。

メソッド本体内では、パラメータ名を変数として使用できます。これらの名前付きパラメータの値は、メソッド呼び出しの引数から得られます。

hello("World")
# => "Hello, World"
hello("All")
# => "Hello, All"

関数をブロックとして使用する

Rubyの多くの関数はブロックを引数として受け取ります。例えば:

[0, 1, 2].map {|i| i + 1}
 => [1, 2, 3]

あなたが望む機能を既に持っているなら、 &method(:fn)を使ってブロックにすることができます:

def inc(num)
   num + 1
end

[0, 1, 2].map &method(:inc)
 => [1, 2, 3]


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow