루비 구문
Ruby syntax![]() | 이 글은 설명서나 안내서처럼 쓰여 있다.(2021년 8월) (이 과 시기 |
이 기사는 루비의 패턴 매칭 구문에 대한 정보가 누락되어 있다.(2021년 8월) |
루비 프로그래밍 언어의 구문은 Perl과 Python의 구문과 대체로 비슷하다.클래스 및 메서드 정의는 키워드로 표시되며, 코드 블록은 키워드 또는 브레이스로 정의할 수 있다.Perl과 대조적으로, 변수는 반드시 시그닐로 접두사를 붙이는 것이 아니다.사용할 경우, 시그널은 변수의 범위 의미론을 변경한다.실제적인 목적을 위해서는 표현과 진술의 구분이 없다.[1][2]줄 바꿈은 의미심장하며 문장의 끝으로 간주된다. 세미콜론은 동등하게 사용될 수 있다.Python과 달리, 들여쓰기는 중요하지 않다.
Python과 Perl과의 차이점 중 하나는 Ruby가 모든 인스턴스 변수를 클래스에 완전히 비공개로 유지하고 접근자 방법을 통해서만 노출시킨다는 것이다.attr_writer
,attr_reader
, 등).C++나 자바와 같은 다른 언어의 "게터"나 "세터" 방식과 달리 루비의 접근자 방식은 메타프로그래밍을 통해 코드 한 줄로 만들 수 있지만, C++와 자바의 전통적인 방식으로도 접근자 방식을 만들 수 있다.이러한 방법의 호출은 괄호를 사용할 필요가 없으므로, 하나의 호출 코드를 수정하거나 C# 및 VB와 유사한 기능을 달성하는 리팩터링을 하지 않고 인스턴스 변수를 전체 함수로 변경하는 것은 사소한 일이다.NET 속성 구성원.
Python의 속성 설명자는 유사하지만 개발 과정에서 절충이 따른다.공개적으로 노출된 인스턴스 변수를 사용하여 Python에서 시작하고 나중에 속성 설명자를 통해 노출된 개인 인스턴스 변수를 사용하도록 구현을 변경한다면, 공용 속성보다는 개인 변수를 사용하도록 클래스 내부의 코드를 조정할 필요가 있을 수 있다.Ruby의 설계는 모든 인스턴스(instance) 변수를 비공개로 강제하지만, 또한 간단한 선언 방법을 제공한다.set
그리고get
방법들이것은 루비에서는 수업시간 밖에서 수업의 내부 구성원에 직접 접근하지 않고, 오히려 수업시간에 메시지를 전달하고 응답을 받는다는 생각과 일치한다.
대화형 세션
Interactive Ruby Shell과 같은 Ruby 셸에서 실행하거나 파일에 저장한 다음 명령줄을 입력하여 실행할 수 있는 예는 다음과 같다.ruby <filename>
.
Classic Hello 월드 예:
놓다 '헬로 월드!'
몇 가지 기본적인 루비 코드:
# 리터럴을 포함한 모든 것은 하나의 대상이기 때문에, 이것은 다음과 같이 작용한다. -199.복근 # => 199 '얼음이 좋다'.길이 # => 11 '추억은 멋지다.'.색인을 달다('u') # => 1 "나이스 데이 맞지?".다운케이스.갈라지다('').유니크.분류하다.합류하다 # => '?acdeinsty'
입력:
인쇄하다 '이름을 입력하십시오.' 이름을 붙이다 = 얻다.텁석거리다 놓다 "여보세요#{이름을 붙이다}."
변환:
놓다 '숫자 하나 대봐.' 번호를 붙이다 = 얻다.텁석거리다 놓다 번호를 붙이다.to_i output_number = 번호를 붙이다.to_i + 1 놓다 output_number.to_s + '는 더 큰 숫자다.'
줄들
루비에는 줄을 정의하는 다양한 방법이 있다.
다음 과제는 동일하다.
a = "\n이것은 이중따옴표로 묶은 끈이다.\n" a = %Q{\n이것은 이중따옴표로 묶은 끈이다.\n} a = %{\n이것은 이중따옴표로 묶은 끈이다.\n} a = %/\n이(가) 이중 인용 문자열\n/ a = <<-블록 이것은 이중따옴표로 묶은 끈이다. 블록
시합을 하다 = 3.14159 "pi is#{시합을 하다}" => "pi는 3.14159"
다음 과제는 동일하며 원시 문자열을 생성한다.
a = '이것은 단음절 끈이다.' a = %q{이것은 단일 따옴표로 묶음
컬렉션
배열 구성 및 사용:
a = [3, '여보세요', 14.5, 1, 2, [6, 15]] a[2] # => 14.5 a.[](2) # => 14.5 a.역행의 # => [6, 15], 2, 1, 14.5, '안녕', 3] a.납작하게 하다.유니크 # => [3, '안녕', 14.5, 1, 2, 6, 15]
연관 배열 구성 및 사용(Ruby에서 해시라고 함):
해시하다 = 해시.새로운 # 해시와 동등한 = {} 해시하다 = { 물을 주다: 'wet', 불: '핫' } # 현재와 같이 이전 라인을 이중화 # 별도의 새 해시 개체에 해시 할당 놓다 해시하다[:화재] # "핫" 인쇄 해시하다.각각의 하다 핵심을, 가치를 매기다 # 또는: hash.각각 실행 키, 값 놓다 "#{핵심을}이다#{가치를 매기다}" 종지부를 찍다 # {:water=}"dv", :fire="hot"}을(를) 반환하고 인쇄: # 물은 젖어 있다. # 불은 뜨겁다 해시하다.삭제하다 :물 # 쌍 :수 => '수'를 삭제하고 '수'를 반환함 해시하다.delete_if { 핵심을,가치를 매기다 가치를 매기다 == '핫'} # 쌍:fire => 'hot'을 삭제하고 {}을(를) 반환
제어 구조물
다음과 같은 경우:
# 임의의 숫자를 생성하여 짝수든 홀수든 출력한다. 만일 랜드(100).짝수? 놓다 "짝짝짝 짝짝이로군." 다른 놓다 "이상해." 종지부를 찍다
블록 및 반복기
코드 블록을 만드는 두 가지 구문:
{ 놓다 '헬로 월드!' } # 교정기를 주의하라. # 또는: 하다 놓다 '헬로 월드!' 종지부를 찍다
코드 블록은 선택적 블록 인수로 메서드에 전달될 수 있다.많은 내장형 방법에는 다음과 같은 주장이 있다.
파일.개방된('file.txt', 'w') 하다 파일 # 'w'는 "쓰기 모드"를 의미한다. 파일.놓다 '문자 몇 개를 썼다.' 종지부를 찍다 # 여기서 파일이 자동으로 닫힘 파일.줄거리를 읽다('file.txt').각각 하다 선을 긋다 놓다 선을 긋다 종지부를 찍다 # => 몇 가지 글을 썼다.
매개 변수-블록이 폐쇄되도록 통과:
# 객체 인스턴스('@'로 표시됨) 변수에서 블록을 기억하십시오. 반항하다 기억하세요.(&a_block) @block = a_block 종지부를 찍다 # 이름을 딴 블록을 주면서 앞의 방법을 호출한다. 기억하세요. { 이름을 붙이다 놓다 "여보세요#{이름을 붙이다}!"} # 폐쇄를 호출한다(이는 자유 변수에 대해 닫히지 않는다는 점에 유의하십시오). @block.부르다('존') # => "안녕, 존!"
익명 함수 만들기:
생식을 하다 { 아그 놓다 아그} 프로크.새로운 { 아그 놓다 아그} 람다 { 아그 놓다 아그} ->(아그) {놓다 아그} # 루비 1.9에 소개
메서드에서 닫기 반환:
반항하다 create_set_and_get(initial_value=0) # 기본 값 0을 기록하십시오. closure_value = initial_value [ 프로크.새로운 { x closure_value = x}, 프로크.새로운 { closure_value } ] 종지부를 찍다 세터, 게터 = create_set_and_get # 두 개의 값 반환 세터.부르다(21) 게터.부르다 # => 21 # 매개변수 변수는 폐쇄를 위한 바인딩으로도 사용될 수 있다. # 따라서 앞의 내용을 다음과 같이 다시 쓸 수 있다. 반항하다 create_set_and_get(closure_value=0) [ 생식을 하다 { x closure_value = x } , 생식을 하다 { closure_value } ] 종지부를 찍다
호출 시 제공된 블록으로 프로그램 제어 흐름 전달:
반항하다 use_hello 양보하다 "안녕" 종지부를 찍다 #선행법을발동해 블록을 넘긴다. use_hello { 끈을 매다 놓다 끈을 매다} # => '안녕'
블록을 사용하여 열거 및 배열 반복:
배열하다 = [1, '안녕', 3.14] 배열하다.각각 { 항목 놓다 항목 } # 인쇄물: # 1 # '안녕' # 3.14 배열하다.every_index { 색인을 달다 놓다 "#{색인을 달다}:#{배열하다[색인을 달다]}" } # 인쇄물: # 0: 1 # 1: '안녕' # 2: 3.14 # 다음은 (a..b) 범위를 사용한다. (3..6).각각 { 숫자 놓다 숫자 } # 인쇄물: # 3 # 4 # 5 # 6 # 다음은 (a...b) 범위를 사용한다. (3...6).각각 { 숫자 놓다 숫자 } # 인쇄물: # 3 # 4 # 5
다음과 같은 방법inject
매개 변수와 블록을 모두 사용할 수 있다.그inject
메서드는 목록의 각 멤버에 대해 반복되며, Aggregate를 유지하는 동안 해당 멤버에서 일부 기능을 수행한다.이것은 ...과 유사하다.foldl
기능 프로그래밍 언어로 기능한다.예를 들면 다음과 같다.
[1,3,5].주사를 놓다(10) { 합계를 내다, 원소의 합계를 내다 + 원소의} # => 19
첫 번째 통과에서 블록은 다음과 같이 10(주입할 인수)을 받는다.sum
, 및 1(배열의 첫 번째 요소)은 다음과 같다.element
이것은 11을 반환하고, 그 다음이 된다.sum
다음 고갯길3에 14를 더하면 3이 되고, 3번째 패스에서 5를 더하면 19가 된다.
열거형과 블록을 사용하여 숫자 1에서 10 사이의 제곱(범위 사용):
(1..10).모으다 { x x*x} # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
또는 각 항목에 대해 메서드를 호출하십시오.map
의 동의어다collect
):
(1..5).지도를 그리다(&:to_f) # => [1.0, 2.0, 3.0, 4.0, 5.0]
반
다음 코드는 명명된 클래스를 정의한다.Person
. 뿐만 아니라initialize
, 새로운 객체를 만들기 위한 일반적인 생성자 , 그것은 두 가지 방법을 가지고 있다: 하나는 오버라이드하는<=>
비교 연산자(그러므로)Array#sort
연령별로 정렬할 수 있음) 및 다른 하나는 다음 항목보다 우선할 수 있음to_s
방법(그러므로)Kernel#puts
출력 형식을 지정할 수 있다.여기,attr_reader
루비에서의 메타프로그래밍의 예시 입니다.attr_accessor
인스턴스(instance) 변수의 getter 및 setter 메서드를 정의하지만attr_reader
더 나은 방법뿐이야어떤 방법에서 마지막으로 평가된 문장은 그 반환가치로 명시적 누락도 허용된다.return
명세서
계급 사람 attr_properties :이름, :age 반항하다 초기화하다(이름을 붙이다, 나이를 먹다) @name, @age = 이름을 붙이다, 나이를 먹다 종지부를 찍다 반항하다 <=>(사람) # 정렬 비교 연산자 @age <=> 사람.나이를 먹다 종지부를 찍다 반항하다 to_s "#{@name}(#{@age})" 종지부를 찍다 종지부를 찍다 무리를 짓다 = [ 사람.새로운("밥", 33), 사람.새로운("크리스", 16), 사람.새로운("아쉬", 23) ] 놓다 무리를 짓다.분류하다.역행의
앞의 코드는 세 개의 이름을 역 연령 순서로 인쇄한다.
밥(33) 애쉬(23) 크리스(16)
Person
상수이며, 에 대한 언급이다.Class
이의를 제기하다
오픈 클래스
루비에서, 수업은 결코 닫히지 않는다: 방법은 항상 기존 수업에 추가될 수 있다.이는 표준 빌트인 클래스를 포함한 모든 클래스에 적용된다.기존 클래스에 대한 클래스 정의를 열기만 하면 되며, 지정된 새로운 콘텐츠가 기존 콘텐츠에 추가된다.표준 라이브러리에 새 방법을 추가하는 간단한 예Time
클래스:
# 루비의 타임클래스를 다시 연다. 계급 시간 반항하다 어제 자아의 - 86400 종지부를 찍다 종지부를 찍다 금일 = 시간.지금 당장 # => 2013-09-03 16:09:37 +0300 어제 = 금일.어제 # => 2013-09-02 16:09:37 +0300
이전에 정의된 클래스에 메소드를 추가하는 것을 종종 원숭이 패칭이라고 부른다.부주의하게 수행될 경우, 이 관행은 이후의 예상치 못한 결과와 코드 확장성 문제를 모두 충돌하게 할 수 있다.
Ruby 2.0 이후, 패치의 범위를 코드 베이스의 특정 영역으로 제한함으로써 원숭이 패치의 잠재적인 부정적인 결과를 줄이기 위해 정밀한 방법을 사용할 수 있었다.
# 루비의 타임클래스를 다시 연다. 모듈 상대 시간확장 다듬다 시간 하다 반항하다 반나절_a_day_ago 자아의 - 43200 종지부를 찍다 종지부를 찍다 종지부를 찍다 모듈 마이모듈 계급 마이클래스 # 정교함을 사용할 수 있도록 허용 사용. 상대 시간확장 반항하다 창문의 시간.지금 당장.반나절_a_day_ago 종지부를 찍다 종지부를 찍다 종지부를 찍다
예외
예외는 다음과 함께 제기된다.raise
전화:
높이다
예외에 선택적 메시지를 추가할 수 있다.
높이다 "이건 메시지야"
프로그래머는 예외를 다음과 같이 지정할 수 있다.
높이다 인수오류, "불법 변론!"
또는 예외 인스턴스를 에 전달할 수 있다.raise
방법:
높이다 인수오류.새로운("불법 변론!")
이 마지막 구조는 두 개 이상의 인수가 필요한 생성자를 포함하는 사용자 지정 예외 클래스의 인스턴스를 생성할 때 유용하다.
계급 파르세어러 < 예외 반항하다 초기화하다(입력하다, 선을 긋다, 양치류) 잘 하는 군요 "구문 분석할 수 없어.'#{입력하다}' 줄서서#{선을 긋다}포지션#{양치류}" 종지부를 찍다 종지부를 찍다 높이다 파르세어러.새로운("푸", 3, 9)
예외는 다음에 의해 처리된다.rescue
절이러한 조항은 다음에서 상속되는 예외를 포착할 수 있다.StandardError
. 예외를 처리할 때 사용할 수 있는 기타 흐름 제어 키워드는else
그리고ensure
:
시작되다 ♪ 뭘 좀 해 ♪ 구조하다 # 핸들 예외 다른 # 예외조항이 제기되지 않을 경우 보증하다 # 예외를 제기했든 안 했든 종지부를 찍다
간단한 구조 조항으로 모든 예외를 잡으려 하는 것은 흔한 실수다.모든 예외를 포착하려면 다음을 기록해야 한다.
시작되다 ♪ 뭘 좀 해 ♪ 구조하다 예외 # 여기 예외 처리 코드. # "구제"만 쓰지 마라; 예외의 하위 클래스인 StandardError만 잡는 것이다. 종지부를 찍다
또는 특정 예외를 포착하십시오.
시작되다 ♪ 뭘 좀 해 ♪ 구조하다 RuntimeError # RuntimeError 및 해당 하위 클래스만 처리 종지부를 찍다
또한 예외 객체를 취급자 조항에 사용할 수 있도록 지정할 수도 있다.
시작되다 ♪ 뭘 좀 해 ♪ 구조하다 RuntimeError => e # 취급, "computer e.to_s"와 같은 e가 포함될 수 있음 종지부를 찍다
또는 가장 최근의 예외가 매직 글로벌에 저장된다.$!
.
다음과 같은 몇 가지 예외도 포착할 수 있다.
시작되다 ♪ 뭘 좀 해 ♪ 구조하다 RuntimeError, 타임아웃::오류 => e # 취급, 아마도 e 관련 종지부를 찍다
메타프로그래밍
루비 코드는 런타임에 클래스 및 방법 정의와 같이 좀 더 엄격한 언어로 고정될 자체 구조의 측면을 프로그래밍 방식으로 수정할 수 있다.이러한 종류의 메타프로그래밍은 보다 간결한 코드를 쓰고 언어를 효과적으로 확장하는데 사용될 수 있다.
예를 들어, 다음의 루비 코드는 내장되어 있는 새로운 메소드를 생성한다.String
색상 리스트에 근거한 클래스.메소드는 문자열의 내용을 각각의 색상으로 스타일링한 HTML 태그로 포장한다.
컬러스 = { 검게 하다: "000", 적색의: "f00", 푸르른: "0f0", 노랑색의: "ff0", 파랑의: "00f", 자홍색: "f0f", 청록색의: "0ff", 백색의: "fff" } 계급 끈 컬러스.각각 하다 색을 칠하다,부호를 붙이다 define_message "in_"#{색을 칠하다}" 하다 "<스판 스타일=\"색상: ##{부호를 붙이다}\">#{자아의}</span>" 종지부를 찍다 종지부를 찍다 종지부를 찍다
생성된 방법은 다음과 같이 사용할 수 있다.
"안녕, 월드!".in_blue => "<스판 스타일=\"색상: #00f\">안녕하십니까, 월드!(</span>)"
다른 많은 언어로 동등한 것을 구현하기 위해서 프로그래머는 각 방법을 써야 할 것이다.in_black
,in_red
,in_green
, 등)을 별도로.
루비 메타프로그래밍의 다른 가능한 용도는 다음과 같다.
- 메서드 호출 차단 및 수정
- 새로운 상속 모델 구현
- 매개 변수에서 클래스를 동적으로 생성
- 자동 객체 직렬화
- 대화형 도움말 및 디버깅
참조
- ^ "[ruby-talk:01120] Re: The value of while..."
In Ruby's syntax, statement is just a special case of an expression that cannot appear as an argument (e.g. multiple assignment).
- ^ "[ruby-talk:02460] Re: Precedence question".
statement [...] can not be part of expression unless grouped within parentheses.