Konwersja block -> proc

[code=ruby]def return_proc ( &proc )
yield
end

return_proc { puts “Moje domknięcie” }[/code]
Chciałem zapytać jak można sprawdzić czy nastąpiła konwersja na proc bloku ? Bo

yield.class yield.class.name yield.is_a? yield
nie działa.

A dlaczego miałaby nie nastąpić? Wstawienie explicite parametru &proc powoduje zawsze jego konwersję na obiekt.
Problem polega na tym, że zamiast yield powinno być return proc, żeby został zwrócony ten obiekt, który znajduje się w zmiennej proc. yield natomiast powoduje jego wykonanie (to samo co proc.call).

Ja tu przepisuję przykłady z książki :] więc proszę być wyrozumiałym … nie rozumiem jeszcze trochę składni &proc - a chciałbym jakoś sprawdzić czy nastąpiła konwersja bo w działaniu różnicy nie widzę i wierzę na razie na słowo …

Różnica w działaniu jest dostrzegalna tylko w wydajności.

Działa to tak: jeśli dodasz parametr formalny &nazwa, to to co zostanie przekazane do funkcji jest automatycznie zamieniane an obiekt Proc. Nadal możesz to wywołać przez yield (działa tak samo jakby parametru formalnego nie było wcale), tyle, że odrobinę wolniej. Możesz też zrobić wywołanie nazwa.call, którego nie można by zrobić, gdyby blok nie został przypisany do zmiennej.

Ogólnie - jeśli chodzi o działanie, to dodanie parametru formalnego (&nazwa) niewiele zmienia. Może się natomiast przydać jeśli chcesz coś robić z tym obiektem (coś więcej niż tylko wywoływać, np. przypisać do zmiennej instancyjnej, albo jakieś inne dziwactwa).

A co jest szybsze - proc czy blok ? I nadal nie wiem jak sprawdzić czy konwersja się dokonała. Kolejna rzecz.

[code=ruby]def fun ( &Integer number )
return number
end

puts fun (“2”)[/code]
taki kod zwróci mi liczbę 2 ?

Czysty blok, bo nie jest tworzony dodatkowy obiekt. Ale to ma znaczenie jak zamierzasz wywoływać to tysiące razy. Ogólnie nie zawracałbym sobie tym za bardzo głowy.

Będzie syntax error :slight_smile: Ruby jest dynamicznie typizowany… We wcześniejszym przykładzie “&proc” to nazwa zmiennej. Ampersand na początku oznacza tyle, że ta zmienna ma być związana z blokiem przekazanym do metody.

Jeśli tylko wyspecyfikujesz ten parametr formalny z ampersandem, to zostanie dokonana konwersja. Nie rozumiem za bardzo jak chciałbyś sprawdzić czy dokonała się konwersja. Do bloku “jako takiego” (czyli nie w postaci obiektu Proc) nie ma dostępu innego niż przez yield (tzn. możesz go tylko wywołać).

Jeśli ten temat Cię tak interesuje to radzę poczytać coś o anonimowych funkcjach w Lispie.