2014-07-18 2 views
0

Je remarque sur la documentation de jbuilder: https://github.com/rails/jbuilderComment fonctionne cette syntaxe:. Objet (variable: symbol1,: symbol2)

json.(@message, :created_at, :updated_at) 

Je l'ai testé moi-même dans un code avec jbuilder et il semble être synonyme de ceci:

json.created_at(@message.created_at) 
json.updated_at(@message.updated_at) 

Mais je n'ai jamais rencontré cette syntaxe avant, et n'a jamais vu une telle chose dans tout autre document rubis ou rails. Où cette fonctionnalité de ruby ​​est-elle documentée? Qu'est-ce que c'est exactement ce qu'il fait, et quelles sont les mises en garde à cet égard?

EDIT:

Après la première réponse, je soupçonne maintenant l'objet json ressemble à quelque chose comme ça, et met en œuvre la méthode call:

class FakeJson 
    def initialize 

    end 

    def call(obj, *methods) 
    methods.each do |method| 
     self.public_send(method, obj.public_send(method)) 
    end 
    end 

    def method_missing(*args) 
    puts "called method with #{args.inspect}" 
    end 
end 

Répondre

1

Comme indiqué here,

prc .() appelle prc.call() avec les paramètres donnés. C'est une syntaxe de sucre pour masquer "call".

Il fonctionne comme:

->x, y, z{x + y + z}.(1, 2, 3) 
# => 6 

Je suppose que json est un proc ou d'un autre objet sur lequel call est défini, et il est call -El avec trois arguments @message, :created_at et :updated_at.

+1

Oh! Je pense que je comprends maintenant. JBuilder a son propre DSL à l'intérieur du bloc où vous créez la sortie json. Je pense que l'objet 'json' pourrait ressembler à quelque chose comme (mon edit ci-dessus) – nzifnab

+1

json est le proc, pas @ message – jshort

+0

@jshort Vous avez raison. Je l'ai corrigé. – sawa

1

Généralement vous vous attendez à voir un point '.' avant un nom de méthode:

"Hello".index("e") 

Où index est le nom de la méthode et "e" est l'argument de ladite méthode. Il se trouve que je entre parenthèses, mais qui ne sont pas requis:

"Hello".index "e" 

Vous penseriez que dans le cas dont vous parlez, que() est le nom de la méthode qui est pas exactement vrai . C'est juste du sucre syntaxique.

Dans le cas d'un objet Proc (ou un objet général qui met en oeuvre #call), obj.(args) est équivalente ou même de obj.call(args) (uniquement dans le cas d'un véritable Proc) obj[args].

+0

Il est en effet syntaxe sucre, et est alambiquée, mais notez que '()' dans '.()' Est en fait ** obligatoire ** ('-> x {x}. 1 # => error'), et n'est pas la même chose que '()' dans un appel de méthode ordinaire, qui est facultatif. Donc, dans un sens, vous pouvez dire '()' lui-même est le nom de la méthode, mais il fonctionne aussi comme '()' pour entourer les arguments comme dans le cas de la méthode '[]'. – sawa

+1

Bon point, notez également -> x, y {x+y}.((4,5)) # => error qui dit essentiellement si les parens externes sont le 'nom de la méthode' alors cette 'méthode' particulière ne permet pas l'utilisation des parens internes comme toutes les autres 'méthodes' ... oui je suis d'accord, alambiqué:). – jshort