수색…


소개

Ruby의 함수는 일련의 작업을 수행하기 위해 체계적이고 재사용 가능한 코드를 제공합니다. 함수는 코딩 프로세스를 단순화하고 중복 논리를 방지하며 코드를 쉽게 따르도록합니다. 이 항목에서는 Ruby의 함수, 인수, 매개 변수, yield 문 및 범위의 선언 및 사용에 대해 설명합니다.

비고

메소드 는 하나 이상의 객체와 연관된 이름이 지정된 블록이며 일반적으로 이름 외에도 매개 변수 목록으로 식별됩니다.

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

메소드 호출은 메소드 이름, 호출 될 오브젝트 (수신자라고도 함) W 명명 된 메소드 매개 변수에 지정된 0 개 이상의 인수 값을 지정합니다. 메소드에서 평가 된 마지막 표현식의 값은 메소드 호출 표현식의 값이됩니다.

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

리시버가 명시 적이지 않은 경우에는 self 입니다.

self
# => main

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

Ruby 프로그래밍 언어 책에서 설명했듯이 많은 언어는 관련 객체가없는 함수와 수신기 객체에서 호출되는 메소드를 구별합니다. Ruby는 순전히 객체 지향 언어이므로 모든 메소드는 하나의 객체와 관련되는 진정한 메소드입니다.

방법 매개 변수 개요

유형 방법 서명 호출 예제 과제
R은 똑같은 def fn(a,b,c) fn(2,3,5) a=2, b=3, c=5
브이 아리아 딕 def fn(*rest) fn(2,3,5) rest=[2, 3, 5]
오류 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}

단일 필수 매개 변수

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

그러나 첫 번째 공급 장치 없이도 두 번째 공급 장치공급할 수는 없습니다. 위치 매개 변수를 사용하는 대신 키워드 매개 변수를 사용해보십시오.

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 ["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.

선언되지 않은 키워드 인수 (double splat) 캡처

** 연산자는 * 연산자와 유사하게 작동하지만 키워드 매개 변수에 적용됩니다.

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 ... } 는 괄호 안에 들어 있지 않습니다. 암묵적으로 뒤 따르는 것입니다. 이것은 또한 하나의 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 , eachtimes 과 같은 것들이 일반적으로 클래스에서 구현된다는 것은 yield 과 관련이 있습니다.

블럭을 받았는지 알아 내고 싶다면 block_given? 사용 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 클래스에 name 메소드를 사용하여 직원 이름이있는 객체를 얻기 위해 each 반복 될 수있는 @employees 목록이 있다고 가정합니다. 우리가 블록을 제공하는 경우, 우리는거야 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

메소드 호출은 메소드 이름, 호출 될 오브젝트 (수신자라고도 함) W 명명 된 메소드 매개 변수에 지정된 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