我已经在 cmets 中提供了答案,但我想提供一个更长的答案来帮助你。看来您是一名年轻的程序员,并且是 Ruby 的新手,所以我想帮助您养成健康的习惯。因此,我重构了您的代码,并在 cmets 中加入了解释更改的资源链接,您可以阅读这些资源链接来帮助了解进行更改的原因。
这些大多是次要问题,但在编写任何类型的生产代码或编写其他人将来可能必须阅读或使用的代码时它们很重要。
# 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。
- 写DRY code。不需要
add(keyVal) 方法,因为它已经由merge 在Hash 中实现。尝试将您想要解决的问题翻译成您可以搜索的内容,在这种情况下,您想要“添加到 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 和编程。所以我的建议是让你考虑这些:
- 您的总体目标的简单英文分步说明是什么?
- 如何用面向对象的逻辑来描述这种解释?
- 您可以编写什么代码来封装该逻辑?
- 您描述逻辑的能力与为该逻辑编写代码的能力之间有什么差距?
然后你可以开始提出具体的问题来填补这些空白。