Ruby 1.8.7在另一个模块中扩展常量

时间:2012-07-25 13:00:36

标签: ruby-on-rails ruby

我需要通过向常量MIME_TYPES哈希添加一些项来扩展现有模块(即Redmine :: MimeType)。

这是我到目前为止所尝试的,它只给了我一个动态的常量分配"错误:

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类型)。

2 个答案:

答案 0 :(得分:1)

除了冻结之外,您可以在许多情况下修改现有常量,而不是尝试重新定义它们。例如,在您的示例中,使用#merge!而不是#merge会改变常量。我不确定你是否必须采取措施来区分当前范围中的定义与继承的定义(,你不想改变任何祖先 - 上游值MIME_TYPES如果有的话。

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

同样令人感兴趣的是#replaceHash和其他人的Array方法:

MIME_TYPES.replace(MIME_TYPES.merge(MIME_TYPES_VIDEO))

干杯!

答案 1 :(得分: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

然后你可以在更进一步的逻辑

中使用这个新常量MERGED_MIME_TYPES