提问人:MMfood 提问时间:2/17/2023 更新时间:2/23/2023 访问量:261
我如何用heredoc插入文本文件的内容,用ruby插入变量
How i can Insert contents of text file with heredoc and variable with ruby
问:
我创建 CLI 时出现问题。我想让用户有机会将他们的数据插入到文本文件中,为此我创建了一个文件并向其中添加了一个 heredoc 我正在尝试从文本文档中获取数据,该文本文档中有一个 heredoc,其中包含一个应该插值的函数 当我尝试显示文件的结果时,我得到了文件的全部内容,包括 heredoc
下面将是一个示例
我试图通过File类解决我的问题
variable_name = File::open("path_directory/file_with_heredoc.txt", "r+")::read
接下来,我决定通过以下方式将变量的值提供给终端
exec("echo #{variable_name}")
终端显示
file = <<-EOM
single text with def result: #{upcase_def("Hello")}
EOM
试图通过结构给出,但结果没有变化
exec("echo #{variable_name.strip}")
我需要做什么才能只获取数据,而不获取 HEREDOC 语法? 我想得到这个结果
"single text with def result: HELLO"
答:
我认为这就是您正在尝试做的事情,但我建议您首先做一些研究,为什么“eval()是邪恶的”。如果文件是用户(或黑客)输入的,您肯定希望在那里进行一些清理或采用完全不同的方法。
def upcase_def(str)
str.upcase
end
data = File.read('file_with_heredoc.txt')
eval(data)
# => " single text with def result: HELLO\n"
评论
exec()
%p
eval("%p" % "foo = 'bar'")
Use File Methods to Read Text Files
A here-doc is really intended to inline long String objects directly into your code. Using it as storage for an external file or the contents of a CLI string argument is like using a saw to pound in a nail. Don't do that.
If you really want to store a here-doc in an external file, you should source that file (e.g. by using Kernel#load) rather than trying to parse it. In your case, this is still a bad idea because:
- You should never trust unsanitized user input.
- The sourced file could contain any Ruby code at all, which makes it at least as bad as Kernel#eval when called on untrusted data.
- If the external file is yours anyway, and you trust its contents, there are much easier ways to do this.
The easiest thing to do is simply read in the text file, either as a single String or as an Array of lines. You do this with File#read or File#readlines; these methods are inherited from the IO module, which is subclassed by File. For example:
# we'll assume the filename to read is the
# first argument to your script; otherwise
# just assign a filename as a String
text_file = ARGV[0]
# @return [String] all lines as a single
# object stored in +str+
str = File.read text_file
# @return [Array<String>] array of lines
# stored in +arr+
arr = File.readlines text_file
评论
.txt
.rb