2016-04-14 30 views
0

我想通過編寫一個動態生成的類方法來幹我的代碼。將變量傳遞到Ruby中的動態生成的類

我想是有多個錯誤類和我有以下代碼

紅寶石

class ChatPolicy::Error < StandardError 
ERROR_CLASSES = [ 
    { class_name: 'UserBlacklisted', message: 'Message 1' }, 
    { class_name: 'UserSuspended', message: 'Message 2' }, 
    { class_name: 'UserNotEligibleToRent', message: 'Message 3' }, 
    { class_name: 'MembershipTierNotAllowed', message: 'Message 4' } 
] 

ERROR_CLASSES.each do |cls| 
    Object.const_set(cls[:class_name], Class.new { 
     attr_reader :object 

     def initialize(object) 
      @object = object 
      @message = cls[:message] 
     end 
    }) 
end 
end 

然而,由於在Class.new {}塊,變量不能被通過。我不能初始化消息變量。我想知道如何才能做到這一點?

回答

2

當您使用def定義方法時,不能在方法定義中引用外部範圍的局部變量,即initialize方法中的cls變量。

可以指的是塊內部的這種局部變量,您可以使用塊創建一個方法define_method

所以在你的榜樣,你可以得到它的工作通過改變線路

def initialize(object) 

define_method(:initialize) do |object| 

現在,因爲該方法的身體是你可以參考cls身體內部的塊。

+0

謝謝@matt。它現在有效,但控制檯發出警告。 '1:警告:頂級常量UserSuspended由ChatPolicy :: Error :: UserSuspended引用我想知道它是如何解決的? –

+0

**更新**實際上它不起作用,因爲當我在控制檯中鍵入ChatPolicy :: Error :: UserSuspended時,它變成了'UserSuspended' –

+0

基於@ mudasobwa的解決方案找到了解決方案。它不應該需要'Object.const_set'只使用'const_set' –

1

However, since in the Class.new {} block, the variable cannot be passed in.

這是不是「變量不能被通過,」這是關於「一個塊中,接收器不同,cls局部變量不能得到解決。」有實現目標兩種可能的方法:

- 直接從什麼是可見查找消息:

@message = ChatPolicy::Error::ERROR_CLASSES.detect do |hash| 
    hash[:class_name] == self.class.name 
end[:message] 

- 或使用class_eval

ERROR_CLASSES.each do |cls| 
    Object.const_set(cls[:class_name], class_eval %Q| 
     Class.new { 
     attr_reader :object 

     def initialize(object) 
      @object = object 
      @message = '#{cls[:message]}' # ⇐ HERE !!! 
     end 
    }|) 
end 

UPD @matt的方法更好;我只爲了歷史目的而留下這個答案。

+0

您和馬特的解決方案都爲您提供正確的解決方案。謝謝 –

相關問題