检查' if(gets = a)'

时间:2015-09-18 03:05:45

标签: ruby class nameerror

请帮我修复我的代码...它一直说名称错误。我如何解决它。我尝试添加$ sign以使其成为全局变量,但它仍然表示名称错误。

class Stack 
  def initialize
    @store = []
  end

  def push (a)
    @store.push (a)
  end

  def pop
    @store.pop
  end
end

puts "Press a or b to add or remove Pinball: " #make the user choose to press a or b to stack
press = gets.downcase 

press = a      # if user selected a, add pinball to array
if (press = a)
  l1 = stack.new
  l1.push(Pinball)
  puts L1
end

press = b    # if user selected b, remove pinball to array
if (press = b)
  r2 = stack.new
  r2.pop
  puts r2
  end
end

3 个答案:

答案 0 :(得分:3)

您的代码有几个问题。我将专注于阅读/处理用户输入。

首先:不要试图通过盲目更改代码来修复错误("我尝试添加$ sign以使其成为全局变量" )。这只会让事情变得更糟。相反,退后一步,尝试理解错误消息。它通常包含一些有用的信息或至少一个指向正确方向的行号。

我经常使用IRB来尝试一小段代码。对于更大的代码,我更喜欢测试驱动开发。

NameError

让我们检查您的代码。该行读取用户输入," downcases"它并将其分配给变量press

press = gets.downcase 

下一行尝试将变量或方法a分配给press并导致错误:

press = a
#=> NameError: undefined local variable or method `a'

Ruby引发了这个错误,因为你没有这样的变量或方法 - a未定义。您可能也不想分配给press,因为它会覆盖用户输入。只需删除该行。

修复用户输入

下一行包含相同的代码:

if (press = a)

根据评论,您想检查"如果用户选择了" 。也许它只是一个印刷错误,但既然你重复了这个错误,那就让它解决:

  • =(一个等号)是赋值运算符,它用于assignment

    v = 5
    v #=> 5
    
  • ==(两个等号)是比较运算符,它用于比较两个对象。如果对象相等则返回true,否则返回false

    1 == 1         #=> true
    1 == 2         #=> false
    
    "foo" == "foo" #=> true
    "foo" == "bar" #=> false
    
    v == 5         #=> true
    v == 3         #=> false
    

    ==通常用于if语句。

返回我们的代码。要检查press是否等于a,我们必须使用比较运算符==

if (press == a)

但同样,a未定义。我们必须将变量 a替换为字符 "a",因为用户输入字符:

if (press == "a")

仍然缺少一个小细节。您是否注意到为了输入 a ,您实际上必须按两个 a return ?两个键都产生一个字符:

  • a 生成"a"
  • return 生成"\n" - 名为newline或行尾(EOL)

gets返回整个输入,包括换行符,因此press实际上包含两个字符:

press #=> "a\n"

有两种选择 - 检查两个字符:

if (press == "a\n")

或者摆脱换行符。因为这是一个常见的操作,Ruby提供了专用的方法String#chomp

  

String的末尾(如果存在)中删除给定记录分隔符,返回新的str

我们可以在阅读字符串后立即调用此方法:

press = gets.chomp.downcase

整个代码:

puts "Press a or b to add or remove Pinball: "
press = gets.chomp.downcase 

if press == 'a'
  # ...
end

请注意,括号可以省略。

其他问题

每次用户输入 a b 时,您的程序当前都会创建一个新堆栈,但您可能希望在单个堆栈中添加元素并从中删除元素。因此,您应该在开头创建此堆栈:

stack = Stack.new

字母大小写非常重要:Stack(大写S)是你的类,而stack(小写)是变量(我可以使用foo或任何其他有效的variable name)。 Stack.new会返回分配给Stack的新stack实例。

到该堆栈的push / pop

if press == 'a'
  stack.push('Pinball')
end

if press == 'b'
  stack.pop
end

您还需要一个循环才能处理多个输入。类似的东西:

loop do
  puts "Press a or b to add or remove Pinball: "
  # ...
end

答案 1 :(得分:1)

我猜测问题是您的班级被称为Stack,但您一直在调用stack.new。请改为Stack.new

答案 2 :(得分:0)

也许这就是你想要的:

class Stack
  def initialize
      @store = []
  end

  def push(a)
      @store.push(a)
  end

  def pop
    @store.pop
  end
end

puts "Press a or b to add or remove Pinball: " #make the user choose to press a or b to stack
press = gets.downcase.strip
puts "press:#{press}"

l1 = Stack.new  # class names should begin with an uppercase letter 

# a or b should be a string
if press == "a" # check the value of two operands are equal or not, you should use `==` operator
  l1.push("Pinball")
  puts "l1: #{l1.inspect}"
elsif press == "b"
  l1.pop()
  puts "l1: #{l1.inspect}"
end

输出:

ress a or b to add or remove Pinball:
a
l1: #<Stack:0x007ff8d18f2a38 @store=["Pinball"]>

Press a or b to add or remove Pinball:
b
l1: #<Stack:0x007f9feb8e4aa8 @store=[]>