2017-01-22 94 views
0

所以我在Ruby中做了一個相當大的應用程序,但是我意識到將一切都作爲一個巨大類中的實例方法是非常複雜的,所以我想將它分解爲嵌套模塊只是這樣更有條理。我已經搜索了StackOverflow,但它似乎並不常見使用嵌套在類中的模塊。嵌套在類中的Ruby模塊

我想了解用簡單的例子類模塊如何嵌套工作:

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 

然後我試圖運行:

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

但我不斷收到此錯誤:

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

回答

0

問題是你的include調用是在實際模塊定義之前itions。

當你編寫一個類定義時,其中的所有內容都會立即執行,除了方法定義之外。例如:

class Foo 
    puts 1 + 1 
end 

將打印2 立即,它不會等到你說Foo.new

解決這個問題的一種方法是將include調用移至類定義的末尾,或將模塊移至頂端。你也可以分開嵌套模塊:

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

將包含的調用移動到底部會給出錯誤:phones.rb:38:在':undefined方法應用程序的#<電話: 0x007fe9c989c4b0>(NoMethodError)'。另外,如果使用你建議的第二種方法,你在哪個類中聲明瞭initialize方法和所有的實例變量? –

+0

您不應該在實例範圍中調用include,因爲您似乎正在從未定義的方法錯誤中進行操作。我的意思是你可以將include調用移到'class Phones'的'end'之前。關於初始化,你可以在任何模塊中定義它。當你包含它們時,你可以將他們所有的實例方法結合起所以如果你定義了多個'initialize',只有其中一個會運行,除非你讓他們調用'super'。 –