2010-03-22 8 views
12

tôi hy vọng để thực hiện một cái gì đó giống như tất cả các plug-in tuyệt vời có cho ruby, vì vậy mà bạn có thể làm điều này:Vượt qua các đối số cho mô-đun có trong Ruby?

acts_as_commentable 
has_attached_file :avatar 

Nhưng tôi có một hạn chế:

Đó phương pháp helper thể chỉ bao gồm một mô-đun; nó không thể xác định bất kỳ biến hoặc phương thức nào.

Lý do cho điều này là bởi vì, tôi muốn các tùy chọn băm để xác định cái gì đó như type, và có thể được chuyển đổi thành một trong nói 20 module khác nhau 'ngựa thồ', tất cả trong số đó tôi có thể tổng hợp trong một dòng như thế này:

def dynamic_method(options = {}) 
include ("My::Helpers::#{options[:type].to_s.camelize}").constantize(options) 
end 

Sau đó, những 'workhorses' sẽ xử lý các tùy chọn, làm những việc như:

has_many "#{options[:something]}" 

đây là những gì cấu trúc như thế nào, và tôi tự hỏi nếu bạn biết t ông mất tích mảnh trong câu đố:

# 1 - The workhorse, encapsuling all dynamic variables 
module My::Module 
    def self.included(base) 
    base.extend ClassMethods 
    base.class_eval do 
     include InstanceMethods 
    end 
    end 

    module InstanceMethods 
    self.instance_eval %Q? 
     def #{options[:my_method]} 
     "world!" 
     end 
    ? 
    end 

    module ClassMethods 
    end 
end 

# 2 - all this does is define that helper method 
module HelperModule 
    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    module ClassMethods 

    def dynamic_method(options = {}) 
     # don't know how to get options through! 
     include My::Module(options) 
    end 

    end 
end 

# 3 - send it to active_record 
ActiveRecord::Base.send(:include, HelperModule) 

# 4 - what it looks like 
class TestClass < ActiveRecord::Base 
    dynamic_method :my_method => "hello" 
end 

puts TestClass.new.hello #=> "world!" 

Đó %Q? Tôi không hoàn toàn chắc chắn làm thế nào để sử dụng, nhưng tôi về cơ bản chỉ là muốn bằng cách nào đó có thể vượt qua options băm từ đó phương pháp helper vào module Workhorse . Điều đó có thể không? Bằng cách đó, mô-đun workhorse có thể định nghĩa tất cả các loại chức năng, nhưng tôi có thể đặt tên cho các biến bất cứ điều gì tôi muốn trong thời gian chạy.

Trả lời

2

Bạn có thể muốn nhìn vào Modularity đá quý , thực hiện chính xác những gì bạn muốn.

3

Tôi đang làm việc trên một cái gì đó tương tự, dựa trên một số mã ruby ​​thông minh tôi đã thấy một lần nhưng bây giờ không thể tìm thấy một lần nữa. Tôi có mọi thứ gần như hoạt động, nhưng nó làm rối tung những thứ như self.included và self.extended trong Module của bạn, vì những lý do rõ ràng có thể làm việc xung quanh, nhưng tôi không thích nó phức tạp như thế nào. Tôi nghĩ có một mẹo mà tôi chưa nghĩ đến sẽ làm cho công việc này hoàn hảo hơn.

Vì vậy, điều này có thể hoặc có thể không hoạt động cho bạn, nhưng những gì tôi đang cố gắng là ý tưởng về một mô-đun ẩn danh được tạo động dựa trên các tùy chọn của bạn. (Tôi nghĩ rằng 'loại' có thể là một từ dành riêng nhưng tôi không chắc chắn, vì vậy hãy nói "tùy chọn" thay thế). Hãy xem ý tưởng này:


Module HelperModule 
    def[](options) 
     Module.new do 
     include HelperModule 
     define_method(:options) { options } 
     end 
    end 

    def options 
    raise TypeError.new("You need to instantiate this module with [], man!") 
    end 
end 

obj = Object.new 
obj.extend(HelperModule) 
obj.options => raises TypeError 

obj = Object.new 
obj.extend(HelperModule[ :my_option => "my_option" ] 
obj.options => { my_option => "my_option } 

Loại gọn gàng, huh? Nhưng chưa đủ tốt cho tôi, bởi vì Module thực tế bạn nhận được từ HelperModule [tùy chọn] không có self.included và self.extended từ HelperModule gốc. Tôi đoán tôi chỉ có thể xác định self.included và self.extended trong module anon, nhưng tôi không thích sự nhầm lẫn mã. Tôi cũng không thích phải nói rõ ràng "bao gồm HelperModule" trong mô-đun ẩn danh, tôi muốn nó giống như "tự", ngoại trừ "bản thân" không có nghĩa là điều đúng ở đó, vì vậy nó không hoạt động .

Ah, chờ đợi, đoán những gì tôi chỉ phát hiện ra: Nếu phương pháp chung này có vẻ như nó sẽ làm việc cho bạn, nó có thể được cung cấp bởi các đá quý paramix: http://rubyworks.github.com/paramix/

0

ActionModel đá quý có thể giúp bạn. Tôi sử dụng nó trong các dự án của mình.

+0

Bạn có thể giải thích về cách thức điều này có thể hữu ích trong trường hợp này không?Nó có thể là hiển nhiên đối với bạn, nhưng câu trả lời hay trên trang web này bao gồm loại thông tin này. Một con trỏ không có giải thích không thực sự là câu trả lời .... – GreenAsJade

+0

Đó là actions_as DSL cho lớp ruby. Bạn có thể chuyển trường và tùy chọn thành hành động (mô-đun), ví dụ: actions_as_searchable: title, ignorecase: true –