ruby 自动执行外部嵌套块的批量删除

fcy6dtqo  于 2023-06-22  发布在  Ruby
关注(0)|答案(2)|浏览(73)

我有大约900个文件需要删除最外面的块,这将是一个非常繁琐和容易出错的手动任务。如何使此过程自动化?
例如,我有一些文件看起来像下面的Ruby示例:

Class1.rb:
# some comments

module OuterModule
  class Class1
    # some code
  end
end

Class2.rb:
# some comments

module OuterModule
  class Class2
    # some code
  end
end

每个文件所需的输出为:

Class1.rb:
# some comments

class Class1
  # some code
end

Class2.rb:
# some comments

class Class2
  # some code
end
cu6pst1q

cu6pst1q1#

让我们首先构造示例中的两个文件。

s1 = <<_
# some comments

module OuterModule
  class Class1
    # some code
  end
end
_

s2 = <<_
# some comments

module OuterModule
  class Class2
    # some code
  end
end
_
strings = [s1, s2]
FILES = ["Class1.rb", "Class2.rb"]
FILES.each_index { |i| File.write(FILES[i], strings[i]) }

参见IO::read和IO::write。注意FileIO的子类,所以它继承了IO的方法。例如,我们通常看到File.read(...)而不是IO.read(...),但两者都可以使用。
现在构造一个简单的方法来显示文件的内容。

def display_files
  FILES.each_index { |i| puts "-------------", File.read(FILES[i]) }
end

检查一下我刚写的两个文件。

display_files
-------------
# some comments

module OuterModule
  class Class1
    # some code
  end
end

-------------
# some comments

module OuterModule
  class Class2
    # some code
  end
end

我们可以使用String #gsub!使用以下正则表达式修改这些文件的内容。

RGX = /^module OuterModule\s*$|^end\s*$|^  /

现在读取每个文件,修改其内容并写入修改后的文件。

FILES.each do |file_name|
  File.write(file_name, File.read(file_name).gsub!(RGX, ''))
end

检查写入的文件。

display_files
-------------
# some comments

class Class1
  # some code
end

-------------
# some comments

class Class2
  # some code
end

正则表达式可以用 * 自由间距模式 * 编写,使其具有自文档性。

RGX = /
        ^                       # match beginning of a line
        module\ OuterModule\s*  # match a literal followed by zero or 
                                # more (*) whitespaces (\s)
        $                       # match the end of a line
      |                         # or
        ^                       # match beginning of a line
        end\s*                  # match a literal followed by zero or 
                                # more (*) whitespaces (\s)
        $                       # match the end of a line
      |                         # or
        ^                       # match beginning of a line
        \ \                     # match two spaces (reduce indentation)
      /x                        # invoke free-spacing mode

请注意,第一步,自由间距模式将删除所有未受保护的空间。保护空格字符的三种常见方法是转义它们(正如我所做的那样),将每个字符包含在字符类([ ])中,并用\s替换它们,表示空格字符。最后一个是要谨慎使用,特别是因为行终止符(例如,\n)是空格。
注意事项:

  • 我假设所有缩进都是两个空格字符。如果不是这种情况(例如,如果使用制表符),则可以相应地修改正则表达式。
  • 为了安全起见,可以选择用新文件名(例如,"Class1_new.rb")写入修改后的文件,然后删除原始文件(例如,"Class1.rb"),然后将新文件重命名为旧文件名。
qacovj5a

qacovj5a2#

谢谢你的建议。
我能够通过以下方式实现这一点:
1.使用IDE的“在文件中替换”功能,搜索词module OuterModule,然后添加一个新行。替换术语为空。
1.在“文件”中替换,搜索词新行+ end
1.在包含所有文件的文件夹中运行rubocop -a .

相关问题