0

我有一个包含许多代码的文件,我想将它们全部重构到自己的文件中。有问题的文件有大约 30k 行,所以我不想手动操作。

每个部分开始:

module MyModule

(我改了这个名字)


是否有按标记拆分文件的功能?当我使用时,File.readlines我找不到分割数组的好方法。

我不在乎你怎么想给他们起名字。

4

3 回答 3

2

我重构了你的代码。

File.read('lib/odin.rb').split(/module Odin/).each do |mod|
    File.open("#{mod[/class (\w+)/, 1]}.rb", "w") do |f| 
        f.write("module Odin")
        f.write(mod)
    end
end
于 2013-05-08T23:58:29.697 回答
1

我找到了答案,详细写下问题。

我将其作为答案发布,但我会将答案奖励给其他有更好解决方案的人:

big_file = File.readlines 'lib/odin.rb'
big_file.
  join(' ').
  split(/module Odin/). 
  map!{|w| w.prepend("module Odin\n") }.
  each do |f| 
    name = "#{f.match(/class ([a-zA-Z]+)/)[1].underscore}.rb"
    File.open(name, "w") do |n| 
      n.write(f)
    end
  end

我还想到了一种根据内容命名输出文件的好方法;但我不在乎你会如何命名它们。

于 2013-05-08T23:46:15.803 回答
1

Ruby 有一个很棒的方法,它是 Enumerable 的一部分,称为slice_before

require 'pp'

modules = DATA.readlines.map(&:chomp).slice_before(/^module MyModule/).map{ |a| a.join("\n") }
pp modules

__END__
module MyModule
  # 1 stuff
end

module MyModule
  # 2 stuff
end

module MyModule
  # 3 stuff
end

这是显示内容的输出modules

["模块 MyModule\n #1 东西\nend\n",
 "module MyModule\n # 2 stuff\nend\n",
 "module MyModule\n # 3 stuff\nend"]

DATA是继承自 Perl 的 Ruby 的花招。之后源文件中的所有内容都__END__被视为“数据”块的一部分,解释器在DATA文件句柄中将其提供给正在运行的代码,并且就像数据文件一样。这意味着我们可以在其上使用 IO 方法,例如readlines,类似于我们使用IO.readlines. 我在这里使用__END__andDATA是因为它们便于简单的测试和简短的脚本。

readlines读取行时不会删除尾随行尾,这就是这样map(&:chomp)做的。DATA.read.split("\n")会完成同样的事情。

slice_before是使这项工作发挥作用的魔力。它需要一个数组并遍历它,创建每次模式找到命中时开始的子数组。之后,这只是在写入文件之前将子数组的内容重新加入单个字符串的情况。

之后,您只需要循环modules,将每个文件保存到不同的文件中:

modules.each.with_index(1) do |m, i|
  File.write("module_#{ i }.rb", m)
end

with_index是 Enumerator 中一个不错的小方法,当我们需要知道我们正在处理的数组中的哪个项目时,它很有用。在这种情况下,它类似于each_with_index我们可以指定起始偏移值。1

于 2013-05-09T04:24:24.580 回答