未在外部.txt文件中填充ruby占位符

未在外部.txt文件中填充ruby占位符,ruby,Ruby,这是我目前拥有的;唯一的问题是外部文件加载时未更新占位符文本,而是占位符文本只显示“[名词]”,而不是在早期程序提示中从用户插入的实际名词 更新使用@tadmans建议进行了清理,但是它仍然没有将用户输入传递到外部.txt文件中的占位符文本 puts "\n\nOnce upon a time on the internet... \n\n" puts "Name 1 website:" print "1. " loc=gets puts "\n\Writ

这是我目前拥有的;唯一的问题是外部文件加载时未更新占位符文本,而是占位符文本只显示“
[名词]
”,而不是在早期程序提示中从用户插入的实际名词

更新使用
@tadmans
建议进行了清理,但是它仍然没有将用户输入传递到外部
.txt
文件中的占位符文本

    puts "\n\nOnce upon a time on the internet... \n\n"
    puts "Name 1 website:"
    print "1. "
    loc=gets
    puts "\n\Write 5 adjectives: "
    print "1. "
    adj1=gets
    print "\n2. "
    adj2=gets
    print "\n3. "
    adj3=gets
    print "\n4. "
    adj4=gets
    print "\n5. "
    adj5=gets
    puts "\n\Write 2 nouns: "
    print "1. "
    noun1=gets
    print "\n2. "
    noun2=gets
    puts "\n\nWrite 1 verb: "
    print "1. "
    verb=gets
    puts "\n\nWrite 1 adverb: "
    print "1. "
    ptverb=gets

string_story = File.read("dynamicstory.txt")

puts string_story
当前输出为(即未填充占位符):


需要注意的是,Ruby字符串插值语法仅在实际Ruby代码中有效,而不适用于外部文件。这些只是简单的字符串

如果你想对这些数据进行粗略的插值,你需要重新构造你的程序,使之易于操作。你最不想做的就是
eval
这个字符串

在编写代码时,请始终考虑将程序分解为具有特定函数且可在各种情况下使用的方法或函数。Ruby通常鼓励代码重用,提倡“干燥原则”,或“不要重复自己”

例如,您的输入方法归结为以下通用方法:

def input(thing, count = 1)
  puts "Name %d %s:" % [ count, thing ]

  count.times.map do |i|
    print '%d. ' % (i + 1)

    gets.chomp
  end
end
在这里,它获取具有任意计数的随机对象的输入。我在这里使用的是
sprintf
样式的格式化程序和
%
,但如果您喜欢,您可以自由使用正则插值。我只是发现它可以减少字符串的混乱,特别是在插入复杂的代码块时

接下来,您需要将该数据组织到一个适当的容器中,以便可以通过编程方式访问它。使用一堆不相关的变量是有问题的。在此处使用散列可以简化:

puts "\n\nOnce upon a time on the internet... \n\n"

words = { }

words[:website] = input('website')
words[:adjective] = input('adjectives', 5)
words[:noun] = input('nouns', 2)
words[:verb] = input('verb')
words[:adverb] = input('adverb')
请注意,现在可以通过对代码行重新排序来改变这些事情的顺序,并且可以通过调整单个数字来更改所需的数量,非常简单

接下来要解决的是插值问题。不要使用Ruby表示法
{…}
,这很难计算,而是使用一些简单的方法。在这种情况下,使用
%verb1
%noun2

def interpolate(string, values)
  string.gsub(/\%(website|adjective|noun|verb|adverb)(\d+)/) do
    values.dig($1.to_sym, $2.to_i - 1)
  end
end
这看起来有点难看,但正则表达式用于识别这些标记,
$1
$2
根据正则表达式中完成的捕获,分别提取单词和数字这两部分。这看起来可能有点高级,但是如果你花时间去理解这个方法,你可以很快地解决相当复杂的问题,而不必大惊小怪。在很多情况下,在解析或重写字符串时都会用到它

下面是一个快速测试方法:

string_story = File.read("dynamicstory.txt")

puts interpolate(string_story, words)
文件的内容如下所示:

One dreary evening while browsing the %website1 website online,
I stumbled accross a %adjective1 Frog creature named Earl.

您还可以调整
interpolate
方法以拾取随机单词。

需要注意的是,Ruby字符串插值语法仅在实际Ruby代码中有效,而不适用于外部文件。这些只是简单的字符串

如果你想对这些数据进行粗略的插值,你需要重新构造你的程序,使之易于操作。你最不想做的就是
eval
这个字符串

在编写代码时,请始终考虑将程序分解为具有特定函数且可在各种情况下使用的方法或函数。Ruby通常鼓励代码重用,提倡“干燥原则”,或“不要重复自己”

例如,您的输入方法归结为以下通用方法:

def input(thing, count = 1)
  puts "Name %d %s:" % [ count, thing ]

  count.times.map do |i|
    print '%d. ' % (i + 1)

    gets.chomp
  end
end
在这里,它获取具有任意计数的随机对象的输入。我在这里使用的是
sprintf
样式的格式化程序和
%
,但如果您喜欢,您可以自由使用正则插值。我只是发现它可以减少字符串的混乱,特别是在插入复杂的代码块时

接下来,您需要将该数据组织到一个适当的容器中,以便可以通过编程方式访问它。使用一堆不相关的变量是有问题的。在此处使用散列可以简化:

puts "\n\nOnce upon a time on the internet... \n\n"

words = { }

words[:website] = input('website')
words[:adjective] = input('adjectives', 5)
words[:noun] = input('nouns', 2)
words[:verb] = input('verb')
words[:adverb] = input('adverb')
请注意,现在可以通过对代码行重新排序来改变这些事情的顺序,并且可以通过调整单个数字来更改所需的数量,非常简单

接下来要解决的是插值问题。不要使用Ruby表示法
{…}
,这很难计算,而是使用一些简单的方法。在这种情况下,使用
%verb1
%noun2

def interpolate(string, values)
  string.gsub(/\%(website|adjective|noun|verb|adverb)(\d+)/) do
    values.dig($1.to_sym, $2.to_i - 1)
  end
end
这看起来有点难看,但正则表达式用于识别这些标记,
$1
$2
根据正则表达式中完成的捕获,分别提取单词和数字这两部分。这看起来可能有点高级,但是如果你花时间去理解这个方法,你可以很快地解决相当复杂的问题,而不必大惊小怪。在很多情况下,在解析或重写字符串时都会用到它

下面是一个快速测试方法:

string_story = File.read("dynamicstory.txt")

puts interpolate(string_story, words)
文件的内容如下所示:

One dreary evening while browsing the %website1 website online,
I stumbled accross a %adjective1 Frog creature named Earl.

您还可以调整
interpolate
方法来选择随机单词。

您的代码会让您认为这些值会被插入到模板中吗?在你的代码中,你在哪里替换这些值?谢谢,Joe-我已经用actual story.txt更新了,它仍然没有打印值,比如'adj2',它被声明、提示和existsA)Ruby中没有参数的方法调用省略了括号,所以它只是
get
,而不是
get()
。B) 大写字母在语法中有特定的含义,用于表示
ClassName
CONSTANT\u NAME
类型,因此方法名和变量名应仅为小写,如
string\u story
。c)考虑使用循环,如<代码> 5次> 请求多个输入,而不是复制粘贴多行代码。