使用ruby切换字符串句子中的单词
我制作了一个在数组中存储名称字符串的程序,它首先使用get.chomp请求用户输入,在键入ADD Name之后,它使用push和DEL Name将名称添加到数组中,要从数组中删除该名称,现在我想输入“REPLACE Name1 Name2”将数组中的Name1替换为Name2。 提前感谢:)使用ruby切换字符串句子中的单词,ruby,Ruby,我制作了一个在数组中存储名称字符串的程序,它首先使用get.chomp请求用户输入,在键入ADD Name之后,它使用push和DEL Name将名称添加到数组中,要从数组中删除该名称,现在我想输入“REPLACE Name1 Name2”将数组中的Name1替换为Name2。 提前感谢:) 您可以将此方法添加到基类中: def replace_names_array(name_to_replace, new_name) @@names_array = @@names_array.map d
您可以将此方法添加到
基类中
:
def replace_names_array(name_to_replace, new_name)
@@names_array = @@names_array.map do |name|
name == name_to_replace ? new_name : name
end
end
您可以将此方法添加到
基类中
:
def replace_names_array(name_to_replace, new_name)
@@names_array = @@names_array.map do |name|
name == name_to_replace ? new_name : name
end
end
这里有很多事情需要注意,但最重要的是 您可以在中的类或模块定义中放置自由格式代码 除了在你没有其他选择的情况下,练习那些令人沮丧的东西 选择,就像您在类或模块级别进行元编程一样 在几乎所有其他情况下,您都希望在 主上下文,即在这些定义之外或定义良好的 可以根据需要调用的方法 深入挖掘,您定义的基类似乎使用类级别 变量独占。这意味着
new
生成的所有对象
即使技术上不同,功能上也是相同的。你可能会做什么
want是一个简单的单例版本:
module NameRegistry
def self.names
@names ||= [ ]
end
end
使用它现在非常简单,我将在稍后演示。下一个
需要修复的是解析器类,它大大减少了它的责任。
你可以用正则表达式定义一个简单灵活的语法,
并且可以很容易地适应更不寻常的用例:
class CommandParser
def parse(line)
case (line)
when /\AADD\s+(.*)\z/i
NameRegistry.names.push($1)
when /\ADEL\s+(.*)\z/i
NameRegistry.names.delete($1)
when /\AREP\s+(.*)\s+WITH\s+(.*)\z/i
if (NameRegistry.names.delete($1))
NameRegistry.names.push($2)
end
when /\AEXIT\z/i
# Signal that this command was terminal
return false
end
# Default to success
true
end
end
这将产生一段如下所示的主代码:
puts "Type ADD 'name' to add a name, DEL 'name' to delete, and EXIT to end program."
parser = CommandParser.new
while (parser.parse(gets.chomp))
puts "Names: #{NameRegistry.names.join(', ')}"
end
这里有很多事情需要注意,但最重要的是 您可以在中的类或模块定义中放置自由格式代码 除了在你没有其他选择的情况下,练习那些令人沮丧的东西 选择,就像您在类或模块级别进行元编程一样 在几乎所有其他情况下,您都希望在 主上下文,即在这些定义之外或定义良好的 可以根据需要调用的方法 深入挖掘,您定义的基类似乎使用类级别 变量独占。这意味着
new
生成的所有对象
即使技术上不同,功能上也是相同的。你可能会做什么
want是一个简单的单例版本:
module NameRegistry
def self.names
@names ||= [ ]
end
end
使用它现在非常简单,我将在稍后演示。下一个
需要修复的是解析器类,它大大减少了它的责任。
你可以用正则表达式定义一个简单灵活的语法,
并且可以很容易地适应更不寻常的用例:
class CommandParser
def parse(line)
case (line)
when /\AADD\s+(.*)\z/i
NameRegistry.names.push($1)
when /\ADEL\s+(.*)\z/i
NameRegistry.names.delete($1)
when /\AREP\s+(.*)\s+WITH\s+(.*)\z/i
if (NameRegistry.names.delete($1))
NameRegistry.names.push($2)
end
when /\AEXIT\z/i
# Signal that this command was terminal
return false
end
# Default to success
true
end
end
这将产生一段如下所示的主代码:
puts "Type ADD 'name' to add a name, DEL 'name' to delete, and EXIT to end program."
parser = CommandParser.new
while (parser.parse(gets.chomp))
puts "Names: #{NameRegistry.names.join(', ')}"
end
你真的,真的,真的不应该把这样的代码放在
类
定义中。这没有用。与用户的任何交互都应该在实际方法中使用,如果使用类,也可以考虑使用<代码>命令= GET.CHOMP.S拆除术(/s++/<)/Cult>来将用户输入分解为一系列单词。然后,您可以对单词使用case
,并使用一个直接向上的where
子句处理每个命令。另一个观察结果是,您可以使用break
来打破循环,因此loop do。。。使用内部的中断
结束
比使用需要操作的任意循环结束变量要好<代码>中断是即时的,设置标志则不是,并且可能不会阻止其他行为的发生。您真的、真的、真的不应该将这样的代码放入类
定义中。这没有用。与用户的任何交互都应该在实际方法中使用,如果使用类,也可以考虑使用<代码>命令= GET.CHOMP.S拆除术(/s++/<)/Cult>来将用户输入分解为一系列单词。然后,您可以对单词使用case
,并使用一个直接向上的where
子句处理每个命令。另一个观察结果是,您可以使用break
来打破循环,因此loop do。。。使用内部的中断
结束
比使用需要操作的任意循环结束变量要好<代码>中断是立即的,设置标志不是,并且可能不会阻止其他行为的发生。