我有一个包含许多代码的文件,我想将它们全部重构到它们自己的文件中。有问题的文件有大约3万行,所以我不想亲自去做。如何通过grep与红宝石分割文件?
每个部分的开始:
module MyModule
(我已经改变了这个名字)
是否有分割每个标记文件的功能?当我使用File.readlines
时我无法找到拆分数组的好方法。
我不在乎你怎么想他们的名字。
我有一个包含许多代码的文件,我想将它们全部重构到它们自己的文件中。有问题的文件有大约3万行,所以我不想亲自去做。如何通过grep与红宝石分割文件?
每个部分的开始:
module MyModule
(我已经改变了这个名字)
是否有分割每个标记文件的功能?当我使用File.readlines
时我无法找到拆分数组的好方法。
我不在乎你怎么想他们的名字。
红宝石具有可枚举的部分称为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
包含输出:
["module MyModule\n # 1 stuff\nend\n", "module MyModule\n # 2 stuff\nend\n", "module MyModule\n # 3 stuff\nend"]
DATA
是Ruby的花招OF-一手从Perl继承而来。 __END__
之后的源文件中的所有内容都被视为“数据”块的一部分,该数据块由DATA
文件句柄中的解释器提供给运行代码,并充当数据文件。这意味着我们可以在其上使用IO方法,例如readlines
,与我们如何使用IO.readlines
类似。我在这里使用__END__
和DATA
,因为它们对于简单测试和简短脚本很方便。
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
是枚举一个不错的方法,当我们需要知道这一个项目是有益的我们正在处理的数组。它类似于each_with_index
,只是我们可以指定起始偏移值,在这种情况下为1
。
我给你的答案,因为'slice_before'是我最需要的方法。你还提供了一些有趣的勘误和琐事,教育了我。这个问题本身只是通过'__DATA__'的使用而变得复杂,但我一定会记住这一点。如果你有一个疯狂的使用案例,我很乐意听到它。 – 2013-05-19 17:25:10
当将类似文件的内容存储在磁盘上或在线可用时,“DATA”是一种方便,而不是浪费时间来显示如何创建样本数据文件并参考它。用于'DATA'的用例? Ruby并没有那么用,但是它被用于很多Perl代码。 – 2013-05-19 17:40:45
此链接有助于解释。 Ruby没有'__DATA__',但其余的都是有效的。 http://docstore.mik.ua/orelly/perl/cookbook/ch07_07.htm – 2013-05-19 17:47:47
我已经找到了答案,详细写出了问题。
我张贴它作为一个答案,但我会颁发的答案给别人,有一个更好的解决方案:
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
我又想到了一个很好的方式来命名基于输出文件内容;但我不在乎你如何去想它们的名字。
我重构了你的代码。
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-09 00:10:45
你是什么意思分裂文件?分成新的文件? – squiguy 2013-05-08 23:42:27
@squiguy是的,进入文件 – 2013-05-08 23:44:26
我强烈建议每次你移动一些东西时手工操作并运行规范,这样你就知道每一步都没有破坏任何东西。这将需要更长的时间,但将是坚实的重构。我绝对不会试图自动化 - 我喜欢自动化的东西。 – kikuchiyo 2013-05-08 23:44:30