메서드에서 두 개 이상의 값 반환


105

메서드에서 여러 값을 반환 할 가능성이 있습니까? 이 같은:

def someMethod()
  return ["a", 10, SomeObject.new]
end

[a, b, c] = someMethod

답변:


160
def sumdiff(x, y)
  return x+y, x-y
end
#=> nil

sumdiff(3, 4)
#=> [7, -1]

a = sumdiff(3,4)
#=> [7, -1]
a
#=> [7, -1]

a,b=sumdiff(3,4)
#=> [7, -1]
a
#=> 7
b
#=> -1

a,b,c=sumdiff(3,4)
#=> [7, -1]
a
#=> 7
b
#=> -1
c
#=> nil

텍스트 서식이 아닌 코드 서식을 사용해야합니다. 줄을 네 칸 들여 쓰기하면 irb의 >>프롬프트로 인한 이상 함 이 사라집니다.
Chris Lutz

4
명시 적 반환은 비 관용적 루비로 간주되기 때문에 반환 값을 명시 적으로 목록에 넣어 암시 적 반환을 사용할 수도 있습니다.def foo_and_bar; ['foo', 'bar']; end
Dennis

43

루비는 제한된 형태의 디스트 럭처링 바인드를 가지고 있습니다 :

ary = [1, 2, 3, 4]
a, b, c = ary
p a # => 1
p b # => 2
p c # => 3

a, b, *c = ary
p c # => [3, 4]

a, b, c, d, e = ary
p d # => 4
p e # => nil

또한 제한된 형태의 구조화 바인딩이 있습니다.

 a = 1, 2, 3
 p a # => [1, 2, 3]

다음과 같이 두 가지 형식을 결합 할 수 있습니다.

a, b = b, a # Nice way to swap two variables

a, b = 1, 2, 3
p b # => 2

def foo; return 1, 2 end
a, b = foo
p a # => 1
p b # => 2

비 구조화 / 구조화 바인딩으로 수행 할 수있는 몇 가지 다른 작업이 있습니다. 나는 표시 연산자를 사용하여 보여주지 않았다 (*오른쪽에 )를 . 중첩을 표시하지 않았습니다 (괄호 사용). 블록이나 메서드의 매개 변수 목록에서 비 구조화 결합을 사용할 수 있다는 것을 보여주지 않았습니다.

다음은 애피타이저입니다.

def foo(((a, b, c, d), e, *f), g, *h)
  local_variables.sort.each do |lvar| puts "#{lvar} => #{eval(lvar).inspect}" end
end

foo([[1, 2, 3], 4, 5, 6], 7, 8, 9)
# a => 1
# b => 2
# c => 3
# d => nil
# e => 4
# f => [5, 6]
# g => 7
# h => [8, 9]

16

여러 값을 반환하는 것이 유용한 경우가 많지만 일반적으로 새로운 개체 요구 사항에 대한 포인터입니다.

즉, 일반적으로 이러한 반환 값이 의미 / 문맥에서 밀접하게 연결되어 있으며 그 자체로 전달됩니다. 그래서이 경우에 저는 이것들을 함께 묶는 새로운 객체를 만들 것입니다. 내가 인식하는 법을 배운 특정 코드 냄새입니다.


4
더 많은 자유, 더 많은 책임. 경험이 풍부한 루비 스트는 그것을 활용하고 아름다운 코드를 작성합니다. 루비 신인은 상황을 악화시킬 수 있습니다.
fengd

1
항상 그런 chunk것은 아니며 그렇지 않으면 존재하지 않을 것입니다. 그래도 훌륭한 원칙. 실제로 코드 냄새. 바위에.
Darth Egregious 2015

6

다음과 같이 배열도 반환 할 수 있습니다.

def sumdiff(x, y)
    [x+y, x-y]
end

기능적으로는

def sumdiff(x, y)
    return x+y, x-y
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.