Appel / application de lambda vs appel de fonction - la syntaxe dans Ruby est différente. Pourquoi?

Je suis un peu nouveau sur Ruby et j'essaie toujours de comprendre certains des principes de conception du langage. Si j'ai raison, l'appel d'expression lambda dans Ruby doit être avec des accolades carrées, tandis que l'appel de fonction " régulier "est avec des accolades"régulières" /rondes.

Y a-t-il une raison particulière pour laquelle la syntaxe est différente? Ou, en d'autres termes, (pourquoi) l'appelant devrait-il savoir s'il appelle une fonction ou applique une expression lambda?

30
demandé sur the Tin Man 2011-06-14 16:57:12

3 réponses

Parce que dans Ruby, les méthodes ne sont pas lambdas (comme, par exemple, en JavaScript).

Les méthodes appartiennent toujours à des objets, peuvent être héritées (par sous-classage ou mixins), peuvent être écrasées dans la classe propre d'un objet et peuvent recevoir un bloc (qui est un lambda). Ils ont leur propre portée pour les variables. Exemple de définition de méthode:

a = :some_variable
def some_method
  # do something, but not possible to access local variable a
end

# call with:
some_method

Cependant lambdas / procs sont des fermetures simples, peut-être stockées dans une variable-rien d'autre:

a = :some_variable
some_lambda = lambda{
  # do something, access local variable a if you want to
}

# call with:
some_lambda[]

Ruby combine les deux approches avec un syntaxe puissante, par exemple, passer des blocs:

def some_method_with_block(a)
  # do something, call given block (which is a lambda) with:
  yield(a) ? 42 : 21
end

# example call:
some_method_with_block(1) do |x|
  x.odd?
end #=> 42
26
répondu J-_-L 2011-06-14 13:56:42

Les appels de méthode Ruby réguliers utilisent () pas des accolades qui sont pour les blocs. Si vous n'aimez pas [] pour appeler un lambda, vous pouvez toujours utiliser le call méthode.

Exemple:

>> by_two = lambda { |x| x * 2 } #=> #<Proc:0x0000000101304588@(irb):1>
>> by_two[5] #=> 10
>> by_two.call(5) #=> 10

Modifier

Dans la nouvelle version de Ruby aussi:

>> by_two.(5) #=> 10

Quant à la raison pour laquelle vous ne pouvez pas simplement faire by_two(5), Quand Ruby voit un bareword, il essaie d'abord de le résoudre en tant que variable locale et si cela échoue en tant que méthode.

29
répondu Michael Kohl 2014-04-27 12:42:04

Si vous voulez des parenthèses, vous pouvez faire

by_two = lambda { |x| x * 2 }
by_two.(5) # => 10

Notez l' . entre by_two et (5).

10
répondu Andrew Grimm 2011-06-14 23:40:44