2015-12-12 2 views
-3

Я хотел бы написать что-то вроде поведения в Yii2, поэтому мне нужно не только модуль, но и опции, чтобы определить, как он работает.Параметры модуля в Ruby

Пример того, что мне нужно:

class User 
    include FullNameModule 
    show_full_lastname false 
    ... 
end 

Я видел такой случай в Paperclip самоцвета:

class User < ActiveRecord::Base 
    attr_accessible :avatar 
    has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png" 
    validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/ 
end 

То, что я сейчас:

module FullNameModule 
    def full_name 
    if show_full_lastname 
     "#@name #@last_name" 
    else 
     "#@name #{@last_name[0]}." 
    end 
    end 

    def self.included klass 
    klass.extend ClassMethods 
    end 


    def show_full_lastname 
    self.class.instance_variable_get('@show_full_lastname') 
    end 

    module ClassMethods 
    def show_full_lastname b 
     @show_full_lastname = b 
    end 
    end 
end 

class User 
    include FullNameModule 
    show_full_lastname false 

    def initialize params 
     @name = params[:name] 
     @last_name = params[:last_name] 
    end 
end 


user = User.new ({name: 'John', last_name: 'Tailor'}) 
p user.full_name 

Он отлично работает, но выглядит уродливый, какой правильный путь?

ответ

1

Почему вы пишете «Методы класса» внутри модуля? Вы должны написать отдельный класс для методов класса и написать его так, чтобы модуль мог быть включен внутри класса, а затем наследовать класс User на этот класс. Я не совсем понимаю цель этого

def self.included klass 
klass.extend ClassMethods 
end 

либо. Модули должны использоваться внутри нескольких классов, в то время как классы предназначены для одиночного наследования. Для этого вам даже не нужен «ClassMethods». Вот лучший способ;

--- Edit ----

На самом деле, вы сделали это гораздо сложнее, чем это необходимо. После 30-минутной сессии возиться с кодом, это то, что я придумал.

module FullNameModule 
def name(b) 
    if b == true 
     return "#@name #@last_name" 
    else 
     return "#{@name} #{@last_name[0]}." 
    end 
    end 
end 

class User 
include FullNameModule 

def initialize params 
    @name = params[:name] 
    @last_name = params[:last_name] 
end 
end 


user = User.new ({name: 'John', last_name: 'Tailor'}) 
p user.name(false) 
+0

Я вижу, о чем вы говорите, но что, если я хочу установить опцию в определении класса, например, в качестве самоцвета Paperclip? Я обновил ответ. – Costa

+0

О «klass.extend ClassMethods» - я прочитал его здесь http://yehudakatz.com/2009/11/12/better-ruby-idioms/ – Costa

+0

Этот параметр настроен, это метод истинный или ложный , Вы можете настроить его в классе, но всегда рекомендуется сохранять код повторно внутри модулей, а не классов. Классы предназначены для объектов, модули для методов. –

Смежные вопросы