2009-12-25 12 views
6

Me pregunto si hay alguna buena razón o incluso una ventaja al tener que invocar Proc s usando proc.call(args) en Ruby, lo que hace que la sintaxis de la función de orden superior sea mucho más detallada y menos intuitiva.¿Por qué Ruby requiere .call para la invocación de Proc?

¿Por qué no solo proc(args)? ¿Por qué hacer una distinción entre funciones, lambdas y bloques? Básicamente, es todo lo mismo, ¿por qué esta sintaxis confusa? ¿O hay algún punto para el que no me doy cuenta?

Respuesta

11

Usted necesidad alguna forma de distinguir entre llamar la Proc y que pasa a su alrededor.

En Python y ECMAScript, es simple: entre paréntesis es una llamada, sin que no lo sea. En Ruby, dejar fuera del paréntesis es también una llamada, por lo tanto, debe haber alguna otra forma de distinguir.

en Ruby 1.8, Proc#call y su alias Proc#[] sirven esa distinción. A partir de Ruby 1.9, hay un nuevo nombre de método permitido () que se llama así obj.() y Proc#() es también un alias para Proc#call.

Por lo tanto, puede llamar a un Proc así:

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

e incluso se puede también definir () para sus propios clases.

BTW: el mismo problema también es la razón por la que tiene que utilizar el método method para obtener un control de un objeto de método.

2

Quieres pasarlo sin llamándolo, ¿verdad? Requerir que sea llamado explícitamente permite eso. De lo contrario, cada vez que tratara de usar el proc como parámetro, terminaría llamándolo.

+2

Expandir: en Ruby, los paréntesis para las llamadas a métodos son opcionales, por lo que el intérprete no puede distinguir entre 'proc', o simplemente pasar el cierre, y' proc' como sinónimo de 'proc()' . – mipadi

+0

Lo que dijo :) – Telemachus

6

En ruby ​​puede tener una variable local y un método que se denominan foo. Suponiendo que el método es privado, la única manera de llamarlo sería foo(args) (self.foo(args) no funcionaría para los métodos privados que no pueden tener un receptor explícito). Si ruby ​​permitiría sobrecargar al operador(), de modo que el foo en foo(bar) puede ser una variable, no habría forma de llamar al método privado foo, cuando también hay una variable local llamada foo.

Tenga en cuenta que con características como define_method y method_missing, no siempre es posible evitar situaciones en las que tiene métodos y variables locales del mismo nombre.

+0

Para dividir los pelos, hay un método privado que ruby ​​permite un receptor explícito para: self.foo = (args), para distinguir entre crear una variable local y llamar al método. –

Cuestiones relacionadas