Почему Ruby требует .call для вызова Proc? - PullRequest
6 голосов
/ 25 декабря 2009

Мне просто интересно, есть ли какая-либо веская причина или даже преимущество в необходимости вызывать Proc s с использованием proc.call(args) в Ruby, что делает синтаксис функции более высокого порядка более многословным и менее интуитивным.

Почему не просто proc(args)? Зачем проводить различие между функциями, лямбдами и блоками? По сути, это все одно и то же, так почему такой запутанный синтаксис? Или в этом есть смысл, которого я не понимаю?

Ответы [ 3 ]

11 голосов
/ 26 декабря 2009

Вам нужно каким-то образом провести различие между вызовом Proc и передачей его вокруг.

В Python и ECMAScript все просто: с круглыми скобками это вызов, без него нет. В Ruby опускание скобок также вызов, поэтому должен быть какой-то другой способ различения.

В Ruby 1.8 Proc#call и его псевдоним Proc#[] служат этому различию. Начиная с Ruby 1.9, obj.(arg) является синтаксическим сахаром для obj.call(arg), а Proc#() является и псевдонимом для Proc#call.

Итак, вы можете назвать Proc вот так:

  • foo.call (1, 2, 3)
  • foo [1, 2, 3]
  • foo. (1, 2, 3)

И вы даже можете определить () для своих собственных классов.

Кстати: та же проблема и в том, почему вы должны использовать метод method, чтобы получить объект метода.

6 голосов
/ 25 декабря 2009

В ruby ​​вы можете иметь локальную переменную и метод с именем foo. Предполагая, что метод является закрытым, единственный способ вызвать его будет foo(args) (self.foo(args) не будет работать для частных методов, которые не могут иметь явного получателя). Если ruby ​​позволит перегрузить оператор (), так что foo в foo(bar) может быть переменной, не будет никакого способа вызвать закрытый метод foo, когда есть также локальная переменная с именем foo.

Обратите внимание, что с такими функциями, как define_method и method_missing, не всегда возможно избежать ситуаций, когда у вас есть методы и локальные переменные с одинаковыми именами.

2 голосов
/ 25 декабря 2009

Вы хотите иметь возможность передавать его по без вызова, верно? Требование, чтобы это было явно вызвано, позволяет это. В противном случае, каждый раз, когда вы пытаетесь использовать proc в качестве параметра, вы в конечном итоге вызываете его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...