2017-01-22 6 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 вызовы до фактического модуля defin 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: в '<верха (обязательно)>«: неопределенный метод приложение»для # <Телефонов: 0x007fe9c989c4b0> (NoMethodError) '. Кроме того, если вы используете второй способ, который вы предложили, в каком классе вы объявляете метод initialize и все переменные экземпляра? –

+0

, вы не должны вызывать include в области экземпляра, поскольку, похоже, вы делаете это из своей неопределенной ошибки метода. Я имел в виду, что вы можете переместить вызовы include прямо перед 'end'' class Phones'. Что касается инициализации, вы можете определить это в любом из модулей. Когда вы включаете их, вы получаете все свои методы экземпляра. Поэтому, если вы определили несколько 'initialize', только один из них запустится, если вы не назовете их' super'. –