2012-07-25 69 views
0

我需要通過向常數MIME_TYPES哈希添加幾個項目來擴展現有模塊(即Redmine :: MimeType)。紅寶石1.8.7在另一個模塊中擴展常量

這是我試過到目前爲止,只有給了我一個「動態的不斷分配」錯誤:

module MimeTypePatch 
    def self.included(base) # :nodoc: 
    base.extend(ClassMethods) 

    base.class_eval do 
     MIME_TYPES_VIDEO = { 
     'video/x-flv' => 'flv,f4v', 
     'video/mpeg' => '*.mpeg *.mpg *.mpe', 
     'video/quicktime' => 'qt,mov', 
     'video/vnd.vivo' => 'viv,vivo', 
     'video/x-msvideo' => 'avi' 
     }.freeze 

     # merge the new mime types with the existing ones 
     MIME_TYPES = MIME_TYPES.merge(MIME_TYPES_VIDEO).freeze 

     EXTENSIONS = MIME_TYPES.inject({}) do |map, (type, exts)| 
     exts.split(',').each {|ext| map[ext.strip] = type} 
     map 
     end 
    end 
    end 
end 

所以我在做什麼錯的,什麼可能是改變現有的恆正確的處理方法另一個模塊?我確實看到在運行時改變一個常量是有點過時的,但我想不出一個更優雅的方法來實現我想要的(檢測視頻MIME類型)。

回答

0

在初始定義之後,您不能將值賦給常量,您必須創建一個新的常量,該常量將具有合併的散列值。從

# merge the new mime types with the existing ones 
MIME_TYPES = MIME_TYPES.merge(MIME_TYPES_VIDEO).freeze 

此行更改爲

# merge the new mime types with the existing ones 
MERGED_MIME_TYPES = MIME_TYPES.merge(MIME_TYPES_VIDEO).freeze 

然後你就可以在進一步的邏輯

+0

有幫助嗎? – abhas 2012-07-26 18:21:59

+0

有點......我並不是真的想要使用這個解決方案,因爲我不想覆蓋/複製redmine的一些方法。我最終只是將我的值添加到核心Hash。在這種情況下似乎更好的解決方案。但謝謝你的建議。 – Dennis 2012-07-30 11:26:07

1

使用這個新常數MERGED_MIME_TYPES除凍結,您可以修改在很多情況下現有常數而不是試圖重新定義它們。例如,在你的例子中使用#merge!而不是#merge會改變常量。我不確定是否需要採取措施來區分當前範圍和繼承範圍中的定義(,如果有任何問題,您不想更改MIME_TYPES的任何祖先上游值)。

MIME_TYPES = {} unless (defined?(MIME_TYPES)) 
MIME_TYPES.merge!(MIME_TYPES_VIDEO) 

的興趣又是Hash#replace方法,Array,及其他:

MIME_TYPES.replace(MIME_TYPES.merge(MIME_TYPES_VIDEO)) 

乾杯!

+0

感謝您的回答。然而,正如你所提到的那樣,問題是哈希被凍結。所以'#merge!'和'#replace'都不能在這種情況下工作。 – Dennis 2012-08-17 10:13:14