Mam metodę wewnątrz metody. Metoda wewnętrzna zależy od uruchamianej pętli zmiennej. Czy to zły pomysł?Czy możliwe jest posiadanie metod zawartych w Methods?
Odpowiedz
AKTUALIZACJA: Ponieważ ta odpowiedź ostatnio wzbudziła pewne zainteresowanie, chciałem zauważyć, że istnieje discussion on the Ruby issue tracker to remove the feature discussed here, namely to forbid having method definitions inside a method body.
Nie, Ruby nie ma metod zagnieżdżonych.
można zrobić coś takiego:
class Test1
def meth1
def meth2
puts "Yay"
end
meth2
end
end
Test1.new.meth1
Ale to nie zagnieżdżony metoda. Powtarzam: Ruby nie ma zagnieżdżonych metod.
Co to jest, jest definicją metody dynamicznej. Po uruchomieniu meth1
zostanie wykonane ciało meth1
. Ciało po prostu zdarza się zdefiniować metodę o nazwie meth2
, dlatego po uruchomieniu meth1
raz, możesz zadzwonić pod numer meth2
.
Ale gdzie jest zdefiniowane meth2
? Cóż, jest to oczywiście nie zdefiniowane jako metoda zagnieżdżona, ponieważ tam nie są to metody zagnieżdżone w Ruby. Jest zdefiniowana jako metoda instancji Test1
:
Test1.new.meth2
# Yay
Także, to będzie oczywiście na nowo przy każdym uruchomieniu meth1
:
Test1.new.meth1
# Yay
Test1.new.meth1.
# test1.rb:3: warning: method redefined; discarding old meth2
# test1.rb:3: warning: previous definition of meth2 was here
# Yay
W skrócie: nie, Ruby nie wsparcia zagnieżdżone metod.
Należy również zauważyć, że w języku Ruby obiekty nie mogą być zamykane, tylko bryły bloków mogą. To praktycznie eliminuje główny przypadek użycia dla metod zagnieżdżonych, ponieważ nawet zagnieżdżone metody wspierane przez Ruby nie mogą używać zmiennych metody zewnętrznej w metodzie zagnieżdżonej.
UPDATE dalej: w później etapie, a następnie, składnia może być ponownie użyty do dodawania metodami łączenia rubinu, które zachowują się w ten sposób, że opisany sposób: byłyby o zakresie sposobu ich zawierającego, tj. niewidoczne i niedostępne poza ich treścią. I prawdopodobnie będą mieli dostęp do leksykalnego zakresu swojej metody zawierania. Jeśli jednak przeczytasz powyższą dyskusję, możesz zauważyć, że matz jest silnie przeciwny metodom zagnieżdżonym (ale wciąż do usuwania zagnieżdżonych definicji metod).
Możesz również pokazać, jak utworzyć lambda zamknięcia w metodzie DRYness lub uruchomić rekursję. – Phrogz
Mam wrażenie, że Ruby może nie mieć zagnieżdżonych metod. –
@ Mark Thomas: Czy zapomniałem wspomnieć, że Ruby nie ma metod zagnieżdżonych? :-) Poważnie: w czasie gdy pisałem tę odpowiedź, były już trzy odpowiedzi, z których każda twierdziła, że Ruby * ma * zagnieżdżone metody. Niektóre z tych odpowiedzi miały nawet poparcie, mimo że były rażąco błędne. Jeden został nawet zaakceptowany przez PO, mimo że był błędny. Fragment kodu, którego odpowiedź używa do udowodnienia, że Ruby obsługuje metody zagnieżdżone, faktycznie udowadnia, że jest odwrotnie, ale najwyraźniej ani przechodnie, ani OP nie zadali sobie trudu, aby to sprawdzić. Tak, dałem jedną właściwą odpowiedź dla każdego złego. :-) –
Nie, nie, Ruby ma zagnieżdżone metody.Sprawdź to:
def outer_method(arg)
outer_variable = "y"
inner_method = lambda {
puts arg
puts outer_variable
}
inner_method[]
end
outer_method "x" # prints "x", "y"
inner_method nie jest metodą, jest funkcją/lambda/proc. Nie ma powiązanej instancji żadnej klasy, więc nie jest to metoda. –
:-D
Ruby zagnieżdżone metod, tylko nie robią to, czego można oczekiwać od nich
1.9.3p484 :001 > def kme; 'kme'; def foo; 'foo'; end; end
=> nil
1.9.3p484 :003 > self.methods.include? :kme
=> true
1.9.3p484 :004 > self.methods.include? :foo
=> false
1.9.3p484 :005 > kme
=> nil
1.9.3p484 :006 > self.methods.include? :foo
=> true
1.9.3p484 :007 > foo
=> "foo"
To nie jest zagnieżdżona metoda ... zobacz odpowiedź * Jörga W Mittaga * dla jasnego zrozumienia. – Hardik
można zrobić coś takiego
module Methods
define_method :outer do
outer_var = 1
define_method :inner do
puts "defining inner"
inner_var = outer_var +1
end
outer_var
end
extend self
end
Methods.outer
#=> defining inner
#=> 1
Methods.inner
#=> 2
Jest to przydatne, gdy robisz rzeczy takie jak pisanie DSL, które wymagają podziału zakresu między metodami. Ale w przeciwnym razie znacznie lepiej radzisz sobie z robieniem czegokolwiek innego, ponieważ zgodnie z innymi odpowiedziami, inner
jest ponownie definiowane, gdy wywoływane jest outer
. Jeśli chcesz tego zachowania, a czasami możesz, jest to dobry sposób, aby go uzyskać.
W rzeczywistości jest to możliwe. Możesz użyć do tego proc/lambda.
def test(value)
inner = ->() {
value * value
}
inner.call()
end
Ruby sposobem jest fałszywy to z mylących hacki, które będą miały niektórzy użytkownicy zastanawiasz się: „Jak się do cholery robi to jeszcze działa?”, Podczas gdy mniej ciekawy będzie po prostu zapamiętać składnię potrzebne do korzystania z rzeczy. Jeśli kiedykolwiek używałeś Rake'a lub Railsa, widziałeś tego rodzaju rzeczy.
Oto taki hack:
def mlet(name,func)
my_class = (Class.new do
def initialize(name,func)
@name=name
@func=func
end
def method_missing(methname, *args)
puts "method_missing called on #{methname}"
if methname == @name
puts "Calling function #{@func}"
@func.call(*args)
else
raise NoMethodError.new "Undefined method `#{methname}' in mlet"
end
end
end)
yield my_class.new(name,func)
end
Co to robi jest zdefiniować metodę najwyższego poziomu, który tworzy klasę i przekazuje go do bloku. Klasa używa method_missing
, aby udawać, że ma metodę o wybranej nazwie. "Wdraża" tę metodę, wywołując lambdę, którą musisz podać. Nadając nazwę jednoliterowej nazwie, można zminimalizować ilość dodatkowego wpisywania, które jest wymagane (co jest tym samym co Rails w jego schema.rb
). mlet
nosi nazwę od Common Lisp form flet
, z wyjątkiem, gdzie f
oznacza "funkcja", m
oznacza "metodę".
go używać tak:
def outer
mlet :inner, ->(x) { x*2 } do |c|
c.inner 12
end
end
Jest możliwe, aby podobny przyrząd, który pozwala na wiele funkcji wewnętrznych, które zostaną zdefiniowane bez dodatkowego gniazdowania, ale to wymaga jeszcze brzydsze siekać w tym rodzaju, który może Cię znaleźć w implementacji Rake'a lub Rspec. Ustalenie, w jaki sposób działa Rspec let!
, dałoby ci długą drogę do stworzenia tak straszliwej obrzydliwości.
- 1. Czy możliwe jest posiadanie hierarchii "#pragma mark"?
- 2. Czy możliwe jest posiadanie "przeciążonych" tablic rejestracyjnych?
- 3. Czy możliwe jest posiadanie indeksu opartego na funkcjach w MySQL?
- 4. Czy możliwe jest posiadanie warunkowych zależności w połknięciu?
- 5. Czy możliwe jest posiadanie wielu atrybutów danych- {imie} w HTML5?
- 6. Czy możliwe jest posiadanie "aplikacji Facebook" w tle?
- 7. Czy możliwe jest posiadanie tablicy hstore w PostgreSQL
- 8. Czy możliwe jest posiadanie niestandardowych atrybutów w tagach AndroidManifest.xml?
- 9. Czy jest możliwe posiadanie "procesowej" instancji Tomcat do celów testowych?
- 10. Czy możliwe jest posiadanie wersji nadrzędnej jako Właściwość dla dzieci?
- 11. Czy możliwe jest posiadanie nie prostokątnego elementu div?
- 12. Ciekawy: czy możliwe jest posiadanie dynamicznych nazw zmiennych danych Ajax?
- 13. Czy możliwe jest posiadanie formularza zagnieżdżonego (formularz: formularz) na wiosnę
- 14. Czy możliwe jest posiadanie delegata jako parametru atrybutu?
- 15. Czy możliwe jest posiadanie wartości atrybutów obejmujących wiele linii?
- 16. Czy możliwe jest przeciążenie wielu metod Clojure w arytmie?
- 17. Czy możliwe jest dynamiczne ładowanie wszystkich plików właściwości zawartych w pakiecie? tj. MyClass.class.getResource ("*. properties");
- 18. Czy możliwe jest posiadanie tablicy wyników w grze "LowestScore" w Game Center?
- 19. Czy jest możliwe posiadanie własności, która jest IEnumerable <T>?
- 20. Czy możliwe jest posiadanie podwójnie zagnieżdżonych tablic znaków wejściowych w html?
- 21. Czy możliwe jest posiadanie deterministycznego ClassCleanup w testowaniu urządzenia MSTest/VS?
- 22. Czy możliwe jest posiadanie wielu krojów czcionek w tym samym widoku tekstowym?
- 23. Czy możliwe jest posiadanie modelowania w asp.net webapi z przesłanym plikiem?
- 24. Czy możliwe jest posiadanie jednego detektora dokumentów do wielu pól tekstowych w Swing?
- 25. Czy możliwe jest posiadanie mapy [String, Any] z nazwą i wartościami nazwanych parametrów w Scali?
- 26. Czy możliwe jest posiadanie uwierzytelnienia Azure AD i konta indywidualnego w jednej aplikacji MVC ASP.NET?
- 27. Czy możliwe jest posiadanie skojarzonego synonimu ze zmiennymi niewymienionymi w klasie typu?
- 28. Czy możliwe jest posiadanie więcej niż jednego pliku wiadomości w strukturze Play
- 29. Czy możliwe jest posiadanie czarno-białego i kolorowego obrazu w tym samym oknie przy użyciu opencv?
- 30. Czy możliwe jest rozszerzenie tablic w C#?
Czy możesz udostępnić przykład kodu lub przynajmniej logiczny odpowiednik tego, co próbujesz zrobić. –