[ruby] Ruby가 i ++ 또는 i-(증가 / 감소 연산자)를 지원하지 않는 이유는 무엇입니까?

사전 / 사후 증가 / 감소 연산자 ( ++--)는 표준 프로그래밍 언어 구문입니다 (적어도 절차 및 객체 지향 언어의 경우).

루비가 왜 그것들을 지원하지 않습니까? 난 당신과 같은 일을 수행 할 수 이해 +=하고 -=있지만, 그냥 그렇게 간결하고 기존의 특히 이후, 그런 일을 제외 이상한 임의 보인다.

예:

i = 0    #=> 0
i += 1   #=> 1
i        #=> 1
i++      #=> expect 2, but as far as I can tell, 
         #=> irb ignores the second + and waits for a second number to add to i

나는 Fixnum불변이라는 것을 이해 하지만 +=, 새로운 것을 instanciate Fixnum하고 설정할 수 있다면, 왜 그렇게하지 ++않습니까?

=캐릭터를 포함하는 과제의 일관성 이 이것의 유일한 이유입니까, 아니면 뭔가 빠졌습니까?



답변

Matz (Yukihiro Matsumoto)가 옛날에 그것을 설명하는 방법은 다음과 같습니다. 스레드 :

Hi,

In message "[ruby-talk:02706] X++?"
    on 00/05/10, Aleksi Niemelä <aleksi.niemela@cinnober.com> writes:

|I got an idea from http://www.pragprog.com:8080/rubyfaq/rubyfaq-5.html#ss5.3
|and thought to try. I didn't manage to make "auto(in|de)crement" working so
|could somebody help here? Does this contain some errors or is the idea
|wrong?

  (1) ++ and -- are NOT reserved operator in Ruby.

  (2) C's increment/decrement operators are in fact hidden assignment.
      They affect variables, not objects.  You cannot accomplish
      assignment via method.  Ruby uses +=/-= operator instead.

  (3) self cannot be a target of assignment.  In addition, altering
      the value of integer 1 might cause severe confusion throughout
      the program.

                            matz.


답변

한 가지 이유는 지금까지 모든 할당 연산자 (즉, 변수를 변경하는 연산자)에 포함 =되어 있기 때문입니다. 추가하면++-- 더 이상 그렇지 않습니다.

또 다른 이유는 사람들 의 행동 ++--종종 혼동 되기 때문입니다 . 적절한 i++예 : 예제에서 의 반환 값 은 실제로 2가 아니라 1입니다 ( i그러나 새 값은 2 임).


답변

OO 언어에서는 일반적이지 않습니다. 실제로 ++스몰 토크에는 “객체 지향 프로그래밍”이라는 용어가 사용 된 언어 가 없습니다 (그리고 루비 언어가 가장 큰 영향을받는 언어). 당신이 의미하는 바는 그것이 C 에서 일반 적이고 C 를 밀접하게 모방하는 언어 라는 것입니다 . 루비는 다소 C와 유사한 구문을 가지고 있지만 C 전통을 고수하는 데 노예가 아닙니다.

왜 루비가 아닌지에 관해서 : Matz는 그것을 원하지 않았습니다. 이것이 정말로 궁극적 인 이유입니다.

스몰 토크에 그러한 것이 존재하지 않는 이유는 변수를 할당하는 것이 근본적으로 다른 종류 라는 언어의 우선 철학의 일부이기 때문입니다 객체에 메시지를 보내는 의 다른 수준에 있습니다. 이 생각은 아마도 루비 디자인에서 Matz에 영향을 미쳤을 것입니다.

루비에 포함시키는 것은 불가능하지 않습니다 . 모두 ++로 변환하는 전처리기를 쉽게 작성할 수 있습니다 +=1. 그러나 Matz는 “숨겨진 과제”를 수행 한 운영자의 아이디어를 좋아하지 않았을 것입니다. 내부에 숨겨진 정수 피연산자가있는 연산자가있는 것도 조금 이상합니다. 그 언어의 다른 연산자는 그런 식으로 작동하지 않습니다.


답변

또 다른 이유가 있다고 생각합니다. ++Ruby에서는 C와 그 후속 작업처럼 원격으로 유용하지 않을 것입니다.

그 이유는 for키워드입니다. C에서는 필수적이지만 루비에서는 대부분 불필요한 것입니다. 루비 반복 대부분 Enumerable에서와 같은 방법으로 수행 each하고 map순회 통해 어떤 데이터 구조 및Fixnum#times 당신이 루프 시간의 정확한 수를 필요로 할 때, 방법.

실제로, 내가 본 한, 대부분의 시간 +=1은 C 스타일 언어에서 Ruby로 새로 이주한 사람들이 사용합니다.

요컨대, 방법 ++--사용 여부는 실제로 의문의 여지 가 있습니다.


답변

나는 그들이 좋아하지 않는 Matz의 추론이 실제로 변수를 새로운 것으로 대체한다고 생각합니다.

전의:

a = SomeClass.new
데프 a.go
  '여보세요'
종료
#이 시점에서 a.go를 호출 할 수 있습니다
#하지만 당신이 a ++를했다면
#는 a = a + 1을 의미합니다.
# 더 이상 a.go를 호출 할 수 없습니다
# 원본을 잃어 버렸을 때

이제 누군가가 #succ를 호출해야한다고 설득 할 수 있다면! 또는 그렇지 않은 것이 더 합리적이며 문제를 피할 수 있습니다. 루비 코어에서 제안 할 수 있습니다.


답변

.+자체 증가 연산자를 정의 할 수 있습니다 .

class Variable
  def initialize value = nil
    @value = value
  end
  attr_accessor :value
  def method_missing *args, &blk
    @value.send(*args, &blk)
  end
  def to_s
    @value.to_s
  end

  # pre-increment ".+" when x not present
  def +(x = nil)
    x ? @value + x : @value += 1
  end
  def -(x = nil)
    x ? @value - x : @value -= 1
  end
end

i = Variable.new 5
puts i                #=> 5

# normal use of +
puts i + 4            #=> 9
puts i                #=> 5

# incrementing
puts i.+              #=> 6
puts i                #=> 6

“class Variable”에 대한 자세한 정보는 ” Fixnum 오브젝트를 증가시키기위한 클래스 변수 “에서 사용할 수 있습니다 .


답변

그리고 그의 저서 “The Well-Grounded Rubyist”에서 David Black의 말에 따르면 :

Ruby의 일부 객체는 변수에 즉시 값으로 저장됩니다. 여기에는 정수, 기호 (: this 모양) 및 특수 객체 true, false 및 nil이 포함됩니다. 이 값 중 하나를 변수 (x = 1)에 지정하면 변수는 값에 대한 참조가 아니라 값 자체를 보유합니다. 실제적으로 이것은 중요하지 않습니다 (그리고이 책의 참고 문헌 및 관련 주제에 대한 논의에서 반복적으로 철자하기보다는 암시 적으로 남겨지는 경우가 많습니다). 루비는 객체 참조의 역 참조를 자동으로 처리합니다. 즉시 정수 값을 포함하는 객체와 달리 문자열에 대한 참조를 포함하는 객체에 메시지를 보내기 위해 추가 작업을 수행 할 필요가 없습니다. 그러나 즉각적인 가치 표현 규칙에는 몇 가지 흥미로운 결과가 있습니다. 특히 정수에 관해서는. 우선, 즉각적인 값으로 표시되는 모든 객체는 얼마나 많은 변수가 할당 되든지 항상 동일한 객체입니다. 하나의 객체 100, 하나의 객체 false 만 있습니다. 정수 바운드 변수의 즉각적이고 고유 한 특성은 Ruby의 증분 및 사후 증가 연산자가 부족하다는 것입니다. 즉, Ruby에서는이를 수행 할 수 없습니다. x = 1 x ++ # 해당 연산자는 없습니다. x에서 1이 바로 존재하게되면 x ++는 1 ++와 같을 것입니다. 즉, 숫자 1을 숫자 2로 변경한다는 것은 의미가 없습니다. 얼마나 많은 변수가 할당 되든지 상관 없습니다. 하나의 객체 100, 하나의 객체 false 만 있습니다. 정수 바운드 변수의 즉각적이고 고유 한 특성은 Ruby의 증분 및 사후 증가 연산자가 부족하다는 것입니다. 즉, Ruby에서는이를 수행 할 수 없습니다. x = 1 x ++ # 해당 연산자는 없습니다. x에서 1이 바로 존재하게되면 x ++는 1 ++와 같을 것입니다. 즉, 숫자 1을 숫자 2로 변경한다는 것은 의미가 없습니다. 얼마나 많은 변수가 할당 되든지 상관 없습니다. 하나의 객체 100, 하나의 객체 false 만 있습니다. 정수 바운드 변수의 즉각적이고 고유 한 특성은 Ruby의 증분 및 사후 증가 연산자가 부족하다는 것입니다. 즉, Ruby에서는이를 수행 할 수 없습니다. x = 1 x ++ # 해당 연산자는 없습니다. x에서 1이 바로 존재하게되면 x ++는 1 ++와 같을 것입니다. 즉, 숫자 1을 숫자 2로 변경한다는 것은 의미가 없습니다.