这是一个伪造的银行应用程序:
class Bank
private def initialize
$login = Hash.new
puts "Welcome to HEIDI BANK!"
end
def add(keyVal)
keyVal.each do |key, value|
$login[key] = value
end
end
def NewUser
puts "What is the name of the user you would like to add?"
user = gets.chomp
puts "What is the password you would add?"
pass = gets.chomp
passsym = pass.to_sym
$login.add(user => passsym)
end
end
you_bank = Bank.new
you_bank.NewUser
当我尝试运行它时,我得到:
Welcome to HEIDI BANK!
What is the name of the user you would like to add?
12
What is the password you would add?
13
然后引发错误:
in `NewUser': undefined method `add' for {}:Hash(NoMethodError)
如何解决此错误?看来我可能必须弄清楚如何调用Bank.add
之类的东西。像数组中的add
一样,哈希是否内置了samp_array.push
函数?
答案 0 :(得分:1)
您将add
定义为Bank
的实例方法,但是您正在$login
上调用它,它是Hash
的实例。在Bank
本身的实例上调用它,可以省略:
def NewUser
...
add(user => passsym)
end
答案 1 :(得分:1)
我已经在评论中提供了答案,但我想提供更长的答案以帮助您。您似乎是一个年轻的程序员,并且是Ruby的新手,所以我想帮助您养成健康的习惯。因此,我对您的代码进行了重构,并添加了注释,以解释更改,并带有指向资源的链接,您可以阅读这些链接以帮助了解更改原因。
这些大多是小问题,但是在编写任何类型的生产代码或编写将来其他人可能必须阅读或使用的代码时,它们都很重要。
# Allows the use of STDIN.noecho which will not echo text input back to the console:
# https://stackoverflow.com/a/29334534/3784008
require 'io/console'
# Use two spaces of indentation for Ruby, not tabs and not 4 spaces:
# https://github.com/rubocop-hq/ruby-style-guide#source-code-layout
class Bank
# The initialize method is not a private method:
# https://stackoverflow.com/q/1567400/3784008
def initialize
# Use single quotes for non-interpolated strings
# https://github.com/rubocop-hq/ruby-style-guide#strings
puts 'Welcome to HEIDI BANK!'
# Don't instantiate the `login` variable here; it should be lazily instantiated:
# http://blog.jayfields.com/2007/07/ruby-lazily-initialized-attributes.html
end
# Use snake_case for method names
# https://github.com/rubocop-hq/ruby-style-guide#naming
def new_user
puts 'What is the name of the user you would like to add?'
user = gets.chomp
puts 'What is the password you would add?'
# Suppress local echo of the password as it is typed
# https://stackoverflow.com/a/29334534/3784008
pass = STDIN.noecho(&:gets).chomp
# Do not call .to_sym on pass; if pass == an Integer then it will raise an exception,
# e.g., 1.to_sym => NoMethodError: undefined method `to_sym' for 1:Integer
{ user => pass }
end
end
然后像以前一样运行它:
you_bank = Bank.new
Welcome to HEIDI BANK!
=> #<Bank:0x00007f8cc9086710>
you_bank.new_user
What is the name of the user you would like to add?
foo
What is the password you would add?
=> {"foo"=>"bar"}
关于原始代码的另外两个注释:
$
)。 this answer有更多说明。如果最终需要在类的实例中访问的变量,则应使用instance variable。add(keyVal)
方法,因为Hash
已经在merge
中实现了该方法。尝试将您要解决的问题翻译成可以搜索的内容,在这种情况下,您要“ 添加到ruby中的哈希”,并且该查询的第一个Google结果是this answer详细说明了操作方法。希望这对您有所帮助。
更新
您在下面问“什么是惰性实例化?”简短的答案是:在需要使用变量之前不要分配变量。例如:
# Bad; don't do this
class Foo
def initialize
# This variable is instantiated when calling `Foo.new`,
# before it needs to be used, and so takes up memory right
# away vs. only once it's needed
@variable_used_by_example_method = 'foobar'
end
def example_method
puts @variable_used_by_example_method
end
end
# Better; okay to do this
class Foo
def initialize
end
def example_method
# This variable is lazily instantiated, that is, it is not
# instantiated until `Foo.new.example_method` is called
@variable_used_by_example_method = 'foobar'
puts @variable_used_by_example_method
end
end
关于将用户名和密码与用户键入的内容进行比较的其他问题,我建议您仔细考虑一下问题,如果仍然不确定,请发布新问题。您提出的问题尚不清楚,我无法给您一个很好的答案。现在,您正在尝试使用代码来确定一切工作原理,并且当您进行尝试和学习时,可以做一些不完全符合面向对象编程设计模式的事情。但是,根据您到目前为止告诉我的内容,我给您的任何答案都可能与这些模式背道而驰,或者太高级了。 (例如,在类似Rails的框架中使用数据库和相关模型)
我不会做第一个,因为那将是一个不好的建议,而我不会做第二个,因为您应该对Ruby和编程有更牢固的了解。因此,我建议您通过以下方式考虑这些问题:
然后,您可以开始提出具体问题,以填补这些空白。