ruby - 루비에서 switch 문을 작성하는 방법



switch-statement conditional (14)

사건 ... 언제

Chuck의 답변에 예제를 추가하려면 다음을 수행하십시오.

매개 변수 사용 :

case a
when 1
  puts "Single value"
when 2, 3
  puts "One of comma-separated values"
when 4..6
  puts "One of 4, 5, 6"
when 7...9
  puts "One of 7, 8, but not 9"
else
  puts "Any other thing"
end

파라미터 없음 :

case
when b < 3
  puts "Little than 3"
when b == 3
  puts "Equal to 3"
when (1..10) === b
  puts "Something in closed range of [1..10]"
end

kikito가 경고 하는 문제 에 유의하십시오.

어떻게하면 루비에서 switch 문을 쓸 수 있습니까?


Answer #1

Ruby 2.0에서는 다음과 같이 case 문에서 lambda를 사용할 수 있습니다.

is_even = ->(x) { x % 2 == 0 }

case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

구조체를 사용하여 사용자 지정 비교기를 쉽게 만들 수도 있습니다. ===

Moddable = Struct.new(:n) do
  def ===(numeric)
    numeric % n == 0
  end
end

mod4 = Moddable.new(4)
mod3 = Moddable.new(3)

case number
when mod4 then puts 'multiple of 4'
when mod3 then puts 'multiple of 3'
end

(예제는 " Ruby 2.0에서 case 문과 함께 사용할 수 있습니까? ").

또는 완전한 수업으로 :

class Vehicle
  def ===(another_vehicle)
    self.number_of_wheels == another_vehicle.number_of_wheels
  end
end

four_wheeler = Vehicle.new 4
two_wheeler = Vehicle.new 2

case vehicle
when two_wheeler
  puts 'two wheeler'
when four_wheeler
  puts 'four wheeler'
end

(예 : " Ruby 사례 선언문 작동 방식 및 수행 방법 "에서 가져온 예제)


Answer #2

Ruby는 switch 문을 작성하기 위해이 case 를 사용합니다.

루비 워드 프로세서에 따라 :

case 문은 case 의 인수 위치에있는 선택적 조건과 절이없는 0 개 이상의 when 절로 구성됩니다. 조건과 일치하는 첫 번째 when 절 (조건이 null 인 경우 Boolean 진리로 평가)이 "wins"되고 해당 코드 스탠자가 실행됩니다. case 문의 값은 성공적인 when 절의 값이거나 해당 절이 없으면 nil 입니다.

case 문은 else 절로 끝날 수 있습니다. 명령문이 쉼표로 구분 된 여러 후보 값을 가질 수있는 각각의 when .

예:

case x
when 1,2,3
  puts "1, 2, or 3"
when 10
  puts "10"
else
  puts "Some other number"
end

짧은 버전 :

case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end

그리고 Honeybadger 의이 블로그는 Ruby Case를 설명합니다.

Ranges 와 함께 사용할 수 있습니다.

case 5
when (1..10)
  puts "case statements match inclusion in a range"
end

## => "case statements match inclusion in a range"

Regex 와 함께 사용할 수 있습니다.

case "FOOBAR"
when /BAR$/
  puts "they can match regular expressions!"
end

## => "they can match regular expressions!"

Procs 및 Lambdas와 함께 사용할 수 있습니다.

case 40
when -> (n) { n.to_s == "40" }
  puts "lambdas!"
end

## => "lambdas"

또한, 자신의 일치 클래스와 함께 사용할 수 있습니다 :

class Success
  def self.===(item)
    item.status >= 200 && item.status < 300
  end
end

class Empty
  def self.===(item)
    item.response_size == 0
  end
end

case http_response
when Empty
  puts "response was empty"
when Success
  puts "response was a success"
end

Answer #3

그것은 case 라고 불리우며 기대했던 것과 비슷하게 작동합니다. 테스트를 구현하는 많은 즐거움이 있습니다.

case 5
  when 5
    puts 'yes'
  else
    puts 'else'
end

지금 약간 재미를 위해 :

case 5 # every selector below would fire (if first)
  when 3..7    # OK, this is nice
  when 3,4,5,6 # also nice
  when Fixnum  # or
  when Integer # or
  when Numeric # or
  when Comparable # (?!) or
  when Object  # (duhh) or
  when Kernel  # (?!) or
  when BasicObject # (enough already)
    ...
end

그리고 초기 case 매개 변수를 생략하고 식을 작성하여 임의의 if / else 체인 (즉, 테스트에 공통 변수가 포함되지 않은 경우에도)을 case 로 대체 할 수있는 것으로 밝혀졌습니다. 필요.

case
  when x.nil?
    ...
  when (x.match /'^fn'/)
    ...
  when (x.include? 'substring')
    ...
  when x.gsub('o', 'z') == 'fnzrq'
    ...
  when Time.now.tuesday?
    ...
end

Answer #4

나는 다음을 사용하기 시작했다.

a = "secondcase"

var_name = case a
  when "firstcase" then "foo"
  when "secondcase" then "bar"
end

puts var_name
>> "bar"

어떤 경우 컴팩트 코드를 도와줍니다.


Answer #5

당신은 더 자연스러운 방식으로 이렇게 할 수 있습니다.

case expression
when condtion1
   function
when condition2
   function
else
   function
end

Answer #6

루비에서는 두 가지 다른 방법으로 사례 표현을 작성할 수 있습니다.

  1. 일련의 "if"문과 유사합니다.
  2. 사례 옆에있는 목표를 지정하고 각 "when"절을 대상과 비교합니다.

첫 번째 방법

age = 20
case 
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end

두 번째 방법

 case params[:unknown]
 when /Something/ then 'Nothing'
 when /Something else/ then 'I dont know'
 end

Answer #7

많은 프로그래밍 언어, 특히 C에서 파생 된 프로그래밍 언어는 소위 Switch Fallthrough를 지원합니다. Ruby에서 동일한 작업을 수행하는 가장 좋은 방법을 찾고 있었고 다른 사람들에게 유용 할 것이라고 생각했습니다.

C와 같은 언어에서 일반적으로 fallthrough는 다음과 같습니다.

switch (expression) {
    case 'a':
    case 'b':
    case 'c':
        // Do something for a, b or c
        break;
    case 'd':
    case 'e':
        // Do something else for d or e
        break;
}

Ruby에서는 다음과 같은 방법으로 동일한 결과를 얻을 수 있습니다.

case expression
when 'a', 'b', 'c'
  # Do something for a, b or c
when 'd', 'e'
  # Do something else for d or e
end

이것은 'b''b' 또는 'c' 넘어 가기 전에 한 블록의 코드를 실행하도록 허용 할 수 없기 때문에 엄격하게 동일하지는 않지만, 대부분 같은 방식으로 유용 할 정도로 유사하다는 것을 대부분 알게됩니다.


Answer #8

사례에 따라 메소드 해시를 사용하는 것이 좋습니다.

비교할 구체적인 값이있는 경우 (간격이 아님) 긴 목록이있는 경우 메소드의 해시를 선언 한 다음 해시에서 관련 메소드를 호출하는 것이 더 효과적입니다.

# Define the hash
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}

# Define the methods
def menu1
  puts 'menu 1'
end

def menu2
  puts 'menu 2'
end

def menu3
  puts 'menu3'
end

# Let's say we case by selected_menu = :a
selected_menu = :a

# Then just call the relevant method from the hash
send(menu[selected_menu])

Answer #9

사용자 환경에서 정규 표현식을 지원하지 않습니까? 예 : Shopify 스크립트 편집기 (2018 년 4 월) :

[오류] : 초기화되지 않은 상수 RegExp

here 및 here 에서 이미 다루었던 여러 방법을 조합 한 해결 방법 :

code = '!ADD-SUPER-BONUS!'

class StrContains
  def self.===(item)
    item.include? 'SUPER' or item.include? 'MEGA' or\
    item.include? 'MINI' or item.include? 'UBER'
  end
end

case code.upcase
when '12345PROMO', 'CODE-007', StrContains
  puts "Code #{code} is a discount code!"
when '!ADD-BONUS!'
  puts 'This is a bonus code!'
else
  puts 'Sorry, we can\'t do anything with the code you added...'
end

나는 클래스 메쏘드 선언문에서 || .include? 보다 우선 순위가 높 .include? . 당신이 ruby-nazi (item.include? 'A') || ... , 내가 이것을 사용 (item.include? 'A') || ... 상상해보십시오 (item.include? 'A') || ... (item.include? 'A') || ... 대신. repl.it 테스트.


Answer #10

위의 답변 중 많은 내용 에서처럼 === 연산자는 case / when 문에서 사용됩니다.

다음은 해당 연산자에 대한 몇 가지 추가 정보입니다.

사례 평등 연산자 : ===

String, Range, Regexp와 같은 Ruby의 내장 클래스 중 상당수는 case-equality, triple equals 또는 threequals라고도하는 === 연산자의 자체 구현을 제공합니다. 각 클래스에서 다르게 구현되므로 호출 된 객체의 유형에 따라 다르게 작동합니다. 일반적으로 오른쪽에있는 객체가 왼쪽에있는 객체에 속하거나 "속해있는 경우"true를 반환합니다. 예를 들어, 객체가 클래스 (또는 그 서브 클래스 중 하나)의 인스턴스인지 여부를 테스트하는 데 사용할 수 있습니다.

String === "zen"  # Output: => true
Range === (1..2)   # Output: => true
Array === [1,2,3]   # Output: => true
Integer === 2   # Output: => true

is_a와 같이 작업에 가장 적합한 다른 방법으로도 동일한 결과를 얻을 수 있습니까? 및 instance_of?

범위 구현 ===

범위 객체에서 === 연산자가 호출되면 오른쪽 값이 왼쪽 범위 내에 있으면 true를 반환합니다.

(1..4) === 3  # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6  # Output: => false

("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false

=== 연산자는 왼쪽 개체의 === 메서드를 호출한다는 점을 기억하십시오. 그래서 (1..4) === 3은 (1..4)와 같습니다. === 3 즉, 왼쪽 피연산자의 클래스는 === 메소드의 구현이 그래서 피연산자 위치는 상호 교환 할 수 없습니다.

정규식 구현 ===

오른쪽의 문자열이 왼쪽의 정규 표현식과 일치하면 true를 반환합니다. / zen / === "연습 zazen 오늘"# 출력 : => 사실 # "연습 zazen 오늘"= ~ / zen /

위의 두 예제 간의 유일한 차이점은 일치하는 항목이있을 경우 ===는 true를 반환하고 = ~는 정수를 반환한다는 것을 의미합니다.이 정수는 Ruby에서 진위 값입니다. 우리는 곧 이것으로 돌아갈 것이다.


Answer #11

case...when 클래스를 처리 할 때 예기치 않게 약간 동작합니다. 이는 === 연산자를 사용하기 때문입니다.

이 연산자는 리터럴에서는 예상대로 작동하지만 클래스에서는 작동하지 않습니다.

1 === 1           # => true
Fixnum === Fixnum # => false

즉, 당신이 case ... when 을하고 싶다면 case ... when 객체의 클래스 위에 case ... when , 이것이 작동하지 않는다는 것을 의미합니다 :

obj = 'hello'
case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

"문자열이 아닙니다"라고 인쇄합니다.

다행히도, 이것은 쉽게 해결됩니다. === 연산자는 클래스와 함께 사용하고 그 클래스의 인스턴스를 두 번째 피연산자로 제공하면 true 반환하도록 정의되었습니다.

Fixnum === 1 # => true

간단히 말해, 위의 코드는 .class 를 제거하여 수정할 수 있습니다.

obj = 'hello'
case obj  # was case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

저는 오늘이 문제에 대한 해답을 찾는 중이었습니다. 그리고 이것은 처음 나타나는 페이지 였기 때문에 같은 상황에서 다른 사람들에게 유용 할 것이라고 생각했습니다.


Answer #12

대신 Ruby는 case 표현식을 사용합니다.

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when "foo", "bar"
  "It's either foo or bar"
when String
  "You passed a string"
else
  "You gave me #{x} -- I have no idea what to do with that."
end

루비는 === 연산자를 사용하여 when 절의 객체와 case 절의 객체를 비교합니다. 예를 들어, 1..5 === x 이고 x === 1..5 .

위와 같이 정교한 when 절을 사용할 수 있습니다. 범위, 계급 및 모든 종류의 것들이 단순한 평등을 테스트하는 것이 아닙니다.

다른 많은 언어의 switch 문과는 달리 Ruby의 case 에는 전환이 없으므로 break when 마다 끝낼 필요가 없습니다. when "foo", "bar" 와 같은 단일 when 절에 여러 일치 항목을 지정할 수도 있습니다.






conditional