2011-03-03 155 views
0

動態創建的模塊,我用一個模式嘗試,我想反饋:紅寶石

module Concerns 
    def AuthenticatedS3Concern(options) 
    AuthenticatedS3ConcernHelper.go(options) 
    end 

    module_function :AuthenticatedS3Concern 

    module AuthenticatedS3ConcernHelper 
    def self.go(options = {:attribute => :photo}) 
     @@auth_attr = options[:attribute] # the photo clip reference 
     @@auth_attr_url = "#{@@auth_attr}_authenticated_url" # set this to do a one time download 

     Module.new do 
     def self.included(base) 
      base.send :include, AuthenticatedS3ConcernHelper::InstanceMethods 
     end  

     class_eval %(
      def #{@@auth_attr}_authenticated_url(time_limit = 7.days) 
      authenticated_url_for('#{@@auth_attr}', time_limit) 
      end 
     ) 
     end 
    end 

    module InstanceMethods  
     def authenticated_url_for(attached_file, time_limit) 
     AWS::S3::S3Object.url_for(self.send(attached_file).path('original'), self.send(attached_file).bucket_name, :expires_in => time_limit) 
     end 
    end  
    end 
end 

哪位能像這樣被使用:

require 'concerns/authenticated_s3_concern' 
require 'concerns/remote_file_concern' 

class Attachment 
    include Concerns.AuthenticatedS3Concern(:attribute => :attachment) 
end 

我很好奇,如果這是一個好方法或一個壞方法或什麼。有沒有更好的方法來完成這種可變定義模塊的東西?

感謝

回答

0

不知道爲什麼你需要的所有模塊。

如果你需要做的就是動態添加動態命名的方法,你可以開始:

def make_me_a_method meth 
    define_method(meth){|param=7| 
    puts param 
    } 
end 

class C 
    make_me_a_method :foo 
end 

C.new.foo(3) 
#=> 3 
1

除了使您的維護開發者的大腦受到傷害,我看不到任何優勢,這樣做。

從我能理解,所有這些代碼所做的就是建立在包括類的實例方法稱爲attribute_name_authenticated_url - 這簡直是對authenticated_url_for.

包裝你可以很容易地進行使用method_missing或定義同樣的事情,調用一個創建實例方法的類方法。 IMO,這種方法要簡單得多,可讀:

module Concerns 
    module AuthenticatedS3 
    def authenticated_url_for(attached_file, time_limit = 7.days) 
     AWS::S3::S3Object.url_for(self.send(attached_file).path('original'), self.send(attached_file).bucket_name, :expires_in => time_limit) 
    end  
    end 
end 

class Attachment 
    include Concerns::AuthenticatedS3 
end 

@attachment = Attachment.new 
@attachment.authenticated_url_for(:attribute_name) 

元編程技術時最好吃不的你想要做什麼的方式獲得。