i18n任务用于枚举的自定义扫描程序

i34xakig  于 2021-09-29  发布在  Java
关注(0)|答案(2)|浏览(430)

我想为i18n任务创建一个自定义扫描程序,它可以检测模型中声明为散列的枚举。
我的枚举声明模式将始终如下所示:

class Conversation < ActiveRecord::Base
  enum status: { active: 0, archived: 1}, _prefix: true
  enum subject: { science: 0, literature: 1, music: 2, art: 3 }, _prefix: true
end

枚举将始终声明为散列,并且始终具有数字散列值,并且在声明末尾始终具有选项_prefix:true。散列中可以有任意数量的值。
我的自定义扫描仪当前看起来如下所示:

require 'i18n/tasks/scanners/file_scanner'
class ScanModelEnums < I18n::Tasks::Scanners::FileScanner
  include I18n::Tasks::Scanners::OccurrenceFromPosition

  # @return [Array<[absolute key, Results::Occurrence]>]
  def scan_file(path)
    text = read_file(path)
    text.scan(/enum\s([a-zA-Z]*?):\s\{.*\W(\w+):.*\}, _prefix: true$/).map do |prefix, attribute|
      occurrence = occurrence_from_position(
          path, text, Regexp.last_match.offset(0).first)
      model = File.basename(path, ".rb") #.split('/').last
      name = prefix + "_" + attribute
      ["activerecord.attributes.%s.%s" % [model, name], occurrence]
    end
  end
end

I18n::Tasks.add_scanner 'ScanModelEnums'

但是,这只返回每个哈希的最后一个元素:
activerecord.attributes.conversation.status_archived activerecord.attributes.conversation.subject_art 如何返回每个散列的所有元素?我希望看到这样的结果:
activerecord.attributes.conversation.status_active activerecord.attributes.conversation.status_archived activerecord.attributes.conversation.subject_science activerecord.attributes.conversation.subject_literature activerecord.attributes.conversation.subject_music activerecord.attributes.conversation.subject_art 作为参考,i18n任务github repo提供了一个自定义扫描仪的示例。
可以在此处找到它使用的文件扫描程序类。

cunj1qz1

cunj1qz11#

这项工作:

def scan_file(path)
  result = []
  text = read_file(path)

  text.scan(/enum\s([a-zA-Z]*?):\s\{(.*)}, _prefix: true$/).each do |prefix, body|
    occurrence = occurrence_from_position(path, text, 
                                            Regexp.last_match.offset(0).first)

    body.scan(/(\w+):/).flatten.each do |attr|
      model = File.basename(path, ".rb")
      name = "#{prefix}_#{attr}" 
      result << ["activerecord.attributes.#{model}.#{name}", occurrence]
    end
  end
  result
end

它类似于“answer”方法,但使用正则表达式获取“{…}”之间的所有内容,然后使用另一个正则表达式获取每个枚举键名。
“answer”版本引发错误的可能原因是它实际上返回的是一个三维数组,而不是两个:
外层 .map 是所有迭代的数组。
每次迭代返回 retval ,这是一个数组。
每个元素 retail 是一个数组 ['key', occurrence] 对。

tag5nh1u

tag5nh1u2#

这不是答案,这只是我的另一次尝试,它输出一个二维数组而不是单个数组:

require 'i18n/tasks/scanners/file_scanner'
class ScanModelEnums < I18n::Tasks::Scanners::FileScanner
  include I18n::Tasks::Scanners::OccurrenceFromPosition

  # @return [Array<[absolute key, Results::Occurrence]>]
  def scan_file(path)
    text = read_file(path)
    text.scan(/enum\s([a-zA-Z]*?):\s\{(.*)\}, _prefix: true/).map do |prefix, attributes|
      retval = []
      model = File.basename(path, ".rb")
      names = attributes.split(",").map!{ |e| e.strip; e.split(":").first.strip }
      names.each do |attribute|
        pos = (Regexp.last_match.offset(0).first + 8 + prefix.length + attributes.index(attribute))
        occurrence = occurrence_from_position(
            path, text, pos)
        name = prefix + "_" + attribute
        # p "================"
        # p type
        # p message
        # p ["activerecord.attributes.%s.%s" % [model, name], occurrence]
        # p "================"
        retval.push(["activerecord.attributes.%s.%s" % [model, name], occurrence])
      end
      retval
    end
  end
end

I18n::Tasks.add_scanner 'ScanModelEnums'

但是,这为第二个检测到的属性提供了一个错误:

gems/i18n-tasks-0.9.34/lib/i18n/tasks/scanners/results/key_occurrences.rb:48:in `each': undefined method `path' for ["activerecord.attributes.conversation.status_archived", Occurrence(app/models/project.rb:3:32:98::)]:Array (NoMethodError)

相关问题