Ruby Language
メソッド
サーチ…
前書き
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
実際、 foreach
、 each
、そして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
キーワードで定義され、その後にメソッド名と括弧で囲まれたオプションのパラメータ名のリストが定義されます。 def
とend
間の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]