2017-01-22 5 views
0

Also habe ich eine ziemlich große Anwendung in Ruby gemacht, aber ich habe festgestellt, dass es ziemlich unorganisiert ist, alles als Instanzmethode in einer riesigen Klasse zu haben, also möchte ich es in verschachtelte Module aufteilen nur so ist es ein bisschen besser organisiert. Ich habe auf StackOverflow gesucht, aber es scheint, dass es nicht so üblich ist, Module zu verwenden, die in einer Klasse verschachtelt sind.Ruby-Module verschachtelt in Klassen

Ich versuche, wie verschachtelte Module unter Verwendung einer einfacheren Beispielklasse arbeiten zu verstehen:

class Phones 

    include Apps 
    include Call 

    attr_accessor :brand, :model, :price, :smartphone 
    def initialize(brand,model,price,smartphone=true) 
    @price = price 
    @brand = brand 
    @model = model 
    @smartphone = smartphone 
    @task = 'stand-by' 
    end 

    module Apps 
    public def camera 
     @task = __method__.to_s 
     puts "Took a picture!" 
     self 
    end 
    public def gallery 
     @task = __method__.to_s 
     puts "Photos!" 
     self 
    end 
    end 

    module Call 
    public def scall 
     @task = __method__.to_s 
     puts "Ring ring!" 
     self 
    end 
    end 

end 

Dann versuche ich zu laufen:

s7 = Phones.new('Samsung','S7 Edge',3000).Apps.camera 

Aber ich erhalte immer diese Fehlermeldung:

...phones.rb:3:in `<class:Phones>': uninitialized constant Phones::Apps (NameError) 

Antwort

0

Das Problem ist Ihre include Anrufe vor dem eigentlichen Modul defin sind itionen.

Wenn Sie eine Klassendefinition schreiben, wird alles darin sofort ausgeführt, mit Ausnahme von Dingen wie Methodendefinitionen. Zum Beispiel:

class Foo 
    puts 1 + 1 
end 

drucken 2 sofort, es wird nicht warten, bis Sie Foo.new sagen.

Eine Möglichkeit, es zu beheben wäre, die include Aufrufe an das Ende der Klassendefinition zu verschieben, oder die Module an die Spitze. Sie können auch die verschachtelte Module trennen:

class Phones 
    module Apps 
    # your stuff here 
    end 
end 

class Phones 
    module Call 
    # stuff 
    end 
end 

# just make sure the previous modules have been defined 
# by the time this code is run 
class Phones 
    include Call 
    include Apps 
end 
+0

die Anrufe auf den Boden umfassen Umzug gibt Fehler: phones.rb: 38: in ' ': nicht definierte Methode Apps' für # (NoMethodError) '. Wenn Sie die zweite vorgeschlagene Methode verwenden, in welcher Klasse deklarieren Sie außerdem die initialize -Methode und alle Instanzvariablen? –

+0

Sie sollten nicht in den Bereich der Instanz aufrufen, da es scheint, dass Sie von Ihrem undefinierten Methodenfehler handeln. Ich meinte, Sie können die Include-Anrufe direkt vor das "Ende" der 'Class Phones' verschieben. Bezüglich der Initialisierung können Sie dies in jedem der Module definieren. Wenn Sie sie einschließen, erhalten Sie alle ihre Instanzmethoden kombiniert. Wenn Sie also mehrere 'initialize' definiert haben, würde nur einer von ihnen laufen, außer Sie nennen sie' super'. –