0

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

4

2 回答 2

1

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

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

同样令人感兴趣的是、和其他的#replace方法:HashArray

MIME_TYPES.replace(MIME_TYPES.merge(MIME_TYPES_VIDEO))

干杯!

于 2012-08-15T16:19:23.980 回答
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在进一步的逻辑中使用这个新常量

于 2012-07-25T13:32:33.150 回答