Ruby & a deux significations opposées, non?

Le & here n'est pas un opérateur de bits mais une chose liée à Proc. Cela peut paraître évident pour ceux qui le connaissent, mais je vais l'écrire car il m'est facile de le comprendre (et il n'y a pas eu d'autre article qui a écrit de cette façon).

En parlant de & en premier lieu

Une notation pour convertir un bloc en un objet Proc. Dans l'exemple le plus simple

def test(&fun)
    fun.call
end

test { p 1 } #=> 1

Ceci est affiché comme 1. -Block {p 1} est passé à fun -Ce fun est converti en un objet Proc par &. -Par conséquent, fun acceptera les appels en utilisant call, qui est l'une des méthodes de Proc. Voilà le calcul.

Au fait, c'est hors sujet, mais en Ruby ・ "Yield est une abréviation qui appelle Proc généré par & argument."

def test
    yield
end

test { p 1 } #=> 1

Mais c'est OK. Shinpuru!

Alors quelle est la prochaine étape?

def test(&fun)
    fun.call
end

proc = Proc.new { p 1 }
test &proc #=> 1

Ceci est également affiché comme 1. Ici d'abord je "(Cette partie est fausse) & est une magie de conversion en Proc, donc même si vous ajoutez & à celui de Proc, c'est toujours Proc, et je me demande si l'objet Proc est passé à la fois dans & proc et & fun." J'ai pensé.

Si ce qui précède est correct, vous devriez supprimer un &. Proc aurait dû être passé tout le temps. Quand je l'essaye réellement ...

def test(fun)
    fun.call
end

proc = Proc.new { p 1 }
test &proc
#=> wrong number of arguments(given 0, expected 1)

cette? C'est une erreur. Qu'est-il arrivé? Vérifions la classe & proc comme test.

proc = Proc.new { p 1 }
p proc.class #=> Proc
# p (&proc).class #=> syntax Error

Apparemment, proc et & proc sont différents. & proc ne semble pas accepter le .class lui-même. Ça devrait être ça. En fait, & proc n'est pas un objet __ __. Document officiel Ruby

Si vous passez un objet Proc à une méthode avec un bloc avec `& ' Agit comme un blocage d'appels.

Il a été écrit correctement. Et dans Ruby, les blocs ne sont pas des objets (en d'autres termes, je pense que Proc vient du désir de traiter les blocs comme des objets).

Ainsi, nous pouvons voir que & a deux significations __. -Conversion du bloc à l'objet Proc -Conversion de l'objet Proc au bloc C'est exactement le contraire.

Hmm ... honnêtement, cela semblait étrange, mais une fois que vous vous y êtes habitué, cela vous semble-t-il plus un ajustement?

De côté

Le code qui a causé l'erreur ci-dessus fonctionne bien si vous le passez à l'état Proc sans utiliser & en premier lieu.

def test(fun)
    fun.call
end

proc = Proc.new { p 1 }
test proc #=> 1

C'était plutôt chouette. Si l'argument n'utilise pas &, plusieurs procs peuvent être passés sans problème (dans le cas d'un argument formel avec &, un seul par méthode est déterminé).

def test(one, two)
    one.call
    two.call
end

proc1 = Proc.new { p 1 }
proc2 = Proc.new { p 2 }

test proc1, proc2
#=> 1
#   2

De cette façon, de par sa conception, il semble qu'il fonctionnera suffisamment comme un langage sans définir de blocs non-Proc.

Cependant, après tout, je veux passer le bloc directement à la carte, etc. comme Ruby, et la notation de rendement mentionnée ci-dessus est difficile à éliminer. Ensuite, & est important pour la lisibilité, alors j'ai pensé que j'aurais probablement une relation à long terme avec ce type. En tant que talent pour y faire face, la signification de & change en fonction du contexte, donc (je pense que cela peut être dit pour tous les types et classes) dans le programme, "Est-ce un proc ou un bloc maintenant?" L'idée actuelle est qu'il est important d'en garder une trace.

référence

Cela a été très utile. Merci beaucoup. Comment utiliser le bloc Ruby / proc / lambda Celui qui contrôle Proc contrôle Ruby (un mensonge)

Recommended Posts

Ruby & a deux significations opposées, non?
java.util a deux classes ArrayList