2011-01-01 3 views
3

Почему добавление «оператора» к методу в то время как оператор присваивания + = нет?Операторы присваивания Ruby

Почему операторы работают так:

ruby-head > 2.+(4)
=> 6

Хотя операторы присваивания работают таким образом:

ruby-head > i = 1
=> 1
ruby-head > i += 1
=> 2
ruby-head > i.+=(1) SyntaxError: (irb):26: syntax error, unexpected '=' i.+=(1) ^from /Users/fogonthedowns/.rvm/rubies/ruby-head/bin/irb:17:in `'

+0

Интересно. Как бы + = отреагировать на повторную реализацию оператора «+»? Возможно, '+ =' является просто синтаксическим сахаром для назначения переменной в результате переменной. + (Некоторое значение). –

+0

Это почти дубликат http://stackoverflow.com/questions/4360810/ruby-operator-method-calls-vs-normal-method-calls – Phrogz

+0

Ваш вопрос: «Почему эта вещь спроектирована так, как есть?» Вы ожидаете ответа иначе, чем «Потому что дизайнер языка решил, что это так?» Вы надеетесь, что сам Мац объяснит свое обоснование дизайна? – Phrogz

ответ

11

Поскольку назначение работает на переменных не объектов и, следовательно, не могут быть реализованы в качестве способа.

+2

Или более фундаментально: поскольку переменные не являются объектами. Если они * были *, можно просто реализовать '=' как метод для переменных. –

+0

Так много для объектов Ruby до конца :( – bigtunacan

0

Потому что += - это всего лишь стенография для полного выражения.

Если это было само сообщение, то добавление поведения оператора для класса потребует определения оператора присваивания для каждой из сокращенных комбинаций в дополнение к уже, вероятно, необходимым операторам для простого назначения и каждому двоичному оператору ,

Трудно представить, что получилось бы для всей этой дополнительной работы, поэтому Ruby рассматривает объединенные операторы присваивания просто как сокращенное выражение для полного выражения.

+0

где + = определено? –

+2

Я не думаю, что это было бы проблемой. Все операторы присваивания можно было просто определить в 'Object' (например, что-то вроде' def + = (o) self = self + o end', который по-прежнему вызывает «NoMethodError» при использовании с объектом, который не отвечает на '+', и дает желаемое поведение для объектов, которые делают - за исключением того, что он не работает конечно). Проблема в том, что вы не можете определять операторы присваивания как методы, потому что вы не можете определять методы, которые работают с переменными. – sepp2k

1

+ = (как я предположил) синтаксический сахар, который использует метод +. Если подкласс или обезьяна патч класс, чтобы изменить поведение +:

class CustomPlus 
    attr_accessor :value 
    def initialize(value) 
    @value = value 
    end 
    def +(other) 
    value + other * 2 
    end 
end 

Тогда результат:

ruby-1.9.1-p378 > a = CustomPlus.new(2) 
=> #<CustomPlus:0x000001009eaab0 @value=2> 
ruby-1.9.1-p378 > a.value 
=> 2 
ruby-1.9.1-p378 > a+=2 
=> 6 
Смежные вопросы