/ / Ruby - zakres blokowy - ruby-on-rails, ruby

Ruby - zakres blokowy - ruby-rails, ruby

Mam metodę, którą chcę inaczej działać w zależności od scenariusza, więc chcę móc przekazać blok do metody i wykonać, jeśli blok zostanie podany.

Jestem jednak zdezorientowany przez zakres zmiennej w bloku, przez który przechodzę.

Na przykład:

def original_method (a, b, opt = {id: nil, id_map: {}})
element_id = (opt[:id_map])

yield if block_given?

end

I nowa metoda, która przechodzi przez blok:

def new_method(a, b, opt)
original_method (a, b, opt) do
if(element_id.include? "some text")
puts "it has some text"
end
end
end

Ale pojawia się błąd:

undefined local variable or method `element_id"

na linii podziału.

Czy można to zrobić?

Odpowiedzi:

5 dla odpowiedzi № 1

Musisz przekazać lokalną zmienną element_id, tak jak yield s argument.

def original_method (a, b, opt = {id: nil, id_map: {}})
element_id = opt[:id_map]
yield(element_id) if block_given? # pass it as argument
end

Następnie zaakceptuj to tak:

def new_method(a, b, opt)
original_method (a, b, opt) do | element_id | # receive as block pramater
if(element_id.include? "some text")
puts "it has some text"
end
end
end

element_id zmienna lokalna została utworzona wewnątrz metody original_method, dlatego jest dostępna tylko w tej metodzie.

Wewnątrz metody new_method, gdy wywołujesz metodę original_method z a blok dołączone do niego, ze względu na zamknięcie możliwość ma dostęp do wszystkich zmiennych w metodzie new_method od początku do punktu, w którym blok jest tworzony.


1 dla odpowiedzi nr 2

Odpowiedz na swoje pośrednie pytanie:

Bloki mają zasięg leksykalnie, co oznacza, że ​​mają dostęp do zmiennych z zakresu, w którym zostały zdefiniowane (w przeciwieństwie do "używanych w").