2012-12-19 15 views
5

To chyba nie jest coś, co powinieneś wypróbować w domu, ale z jakiegoś powodu próbowałem stworzyć szereg metod w Ruby.Ruby: metody jako elementy tablicy - jak działają?

Zacząłem od zdefiniowania dwóch metod.

irb(main):001:0> def test1 
irb(main):002:1> puts "test!" 
irb(main):003:1> end 
=> nil 
irb(main):004:0> def test2 
irb(main):005:1> puts "test2!" 
irb(main):006:1> end 
=> nil 

Dziwna rzecz dzieje się, gdy próbujesz umieścić ją w rzeczywistej tablicy. Wydaje się, że działa obie metody.

irb(main):007:0> array = [test1, test2] 
test! 
test2! 
=> [nil, nil] 

A potem tablica jest pusta.

irb(main):008:0> puts array 


=> nil 

Czy ktoś może mi wyjaśnić, dlaczego uruchamia metody? Poza tym całe ćwiczenie poważnie potrzebuje egzorcysty?

Odpowiedz

14

To, co przechowujesz w swojej macierzy, jest wynikiem wywoływania twoich metod, a nie samych metod.

def test1 
    puts "foo!" 
end 

def test2 
    puts "bar!" 
end 

można przechowywać odniesienia do rzeczywistych metod, takich jak ten:

> arr = [method(:test1), method(:test2)] 
# => [#<Method: Object#test1>, #<Method: Object#test2>] 

Później można nazwać odwołuje metod takich jak to:

> arr.each {|m| m.call } 
foo! 
bar! 
+0

Och, więc to jest możliwe. Miły! – Nekkoru

1

Jeśli miał metodę square i chciał stworzyć tablicę z wartościami kwadratowych 2 i 4, należy napisać

array = [square(2), square(4)] 

tutaj robisz dokładnie to samo, tyle że swoimi metodami badań don Cokolwiek zwróci, dlatego ostateczna wersja array wydaje się pusta (w rzeczywistości zawiera ona [nil, nil]).

+0

Definicje metod w tym przypadku zwracają 'nil', jak pokazano na rysunku. PO niesłusznie twierdzi, że stało się puste; nie jest. Zostały wydrukowane puste linie reprezentujące dwa wystąpienia 'nil', które ma tablica. – sawa

+0

@sawa Masz rację, moja odpowiedź nie była wystarczająco precyzyjna. Edytowałem. – alestanis

1

Twoja tablica nigdy nie zawiera niczego innego niż dwie wartości zerowe. Podstępuję cię, stawiając sznurki podczas oceniania. Ale wartość zwracana każdej funkcji wciąż jest zerowa.

1

Twój kod uruchamia dwie metody, ponieważ tak naprawdę wywołujesz metody, gdy mówisz "test1" i "test2" - nawiasy są opcjonalne dla wywołań metodowych ruby.

Ponieważ obie twoje metody zawierają tylko "puts", która zwraca zero, twoja wynikowa tablica jest po prostu tablicą dwóch zer.

3

@alestanis wyjaśnił przyczynę dobrze. Jeśli próbowali zapisać metod, można zrobić to, co mówi Lars Haugseth czy można zrobić folllowing:

test1 = Proc.new { puts "test!" } 
test2 = Proc.new { puts "test2!" } 
a = [test1, test2] 

To może uczynić kod o wiele bardziej czytelny.

Oto bieg irb.

1.9.3p194 :009 > test1 = Proc.new { puts "test!" } 
=> #<Proc:[email protected](irb):9> 
1.9.3p194 :010 > test2 = Proc.new { puts "test2!" } 
=> #<Proc:[email protected](irb):10> 
1.9.3p194 :011 > a = [test1, test2] 
=> [#<Proc:[email protected](irb):9>, #<Proc:[email protected](irb):10>] 
0

Oto moje dwa centy warte. Opierając się na już opublikowanych rozwiązaniach, jest to przykład działającego przykładu. Dla niektórych może to być przydatne, ponieważ zawiera argumenty metody i użycie self (która odnosi się do instancji klasy PromotionalRules, gdy jest tworzona) oraz tablica symboli, która jest zgrabna - mam to z dokumentów Ruby w metodzie #send here. Mam nadzieję, że to pomoże komuś!

class PromotionalRules 
    PROMOTIONS = [:lavender_heart_promotion, :ten_percent_discount] 

    def apply_promotions total, basket 
    @total = total 

    if PROMOTIONS.count > 0 
     PROMOTIONS.each { |promotion| @total = self.send promotion, @total, basket } 
    end 

    @total.round(2) 
    end 

    def lavender_heart_promotion total, basket 
    if two_or_more_lavender_hearts? basket 
     basket.map { |item| total -= 0.75 if item == 001 } 
    end 
    total 
    end 

    def two_or_more_lavender_hearts? basket 
    n = 0 
    basket.each do |item| 
     n += 1 if item == 001 
    end 
    n >= 2 
    end 

    def ten_percent_discount total, *arg 
    if total > 60.00 
     total = total - total/10 
    end 
    total 
    end 
end 

Dziękuję wszystkim za pomoc. Uwielbiam open-sourceową naturę kodowania - wątki stają się coraz lepsze, gdy ludzie sprawdzają swoje rozwiązania!

Powiązane problemy