使用ruby切换字符串句子中的单词

使用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

我制作了一个在数组中存储名称字符串的程序,它首先使用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 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。。。使用内部的
中断
结束
比使用需要操作的任意循环结束变量要好<代码>中断是立即的,设置标志不是,并且可能不会阻止其他行为的发生。