看起来您正在尝试编写类似于此的东西,这是惯用的 Ruby,以及我们如何循环对象的实例,调用该对象中的特定方法:
class User
def initialize(user, pass, country=nil)
@user = user
@pass = pass
@country = country
end
def user
@user
end
end
pass1 = User.new( 'Kras', 'zim', 'DE' )
pass2 = User.new( 'Hanna', 'Ooma' )
[pass1, pass2].each do |o|
puts o.user
end
其中,运行时,输出:
Kras
Hanna
请注意,我没有在方法内打印值,而是检索它的值,然后打印它。这让我可以分层构建功能。我可以有一个print_user
方法,但我会坚持它可以做什么:
def print_user
puts @user
end
它只输出到控制台,或者 STDOUT 指向的任何地方。如果我需要将其写入文件,则必须编写另一个采用文件名的方法。如果我想将值发送到数据库,我必须编写另一个采用数据库 DSN 的方法。这很愚蠢,相反,我的对象会操纵并返回有关其自身的东西,然后我会有一些外部方法来处理我返回的值的 I/O。
回到您的代码:看起来您正在尝试使用方法来创建变量的状态,这是可行的,但实际上并不是您应该这样做的方式。有时我们想要整体切换对象的设置,但通常我们会将其作为类中的方法进行,可能是这样的:
class User
attr_reader :favorite_color, :favorite_food
def initialize(user, pass, country=nil)
@user = user
@pass = pass
@country = country
@favorite_color = 'orange'
@favorite_food = 'pumpkins'
end
def change_color_and_food(c, f)
@favorite_color = c
@favorite_food = f
end
end
pass1 = User.new( 'Kras', 'zim', 'DE' )
pass1.change_color_and_food('red', 'beets')
运行让我们将食物和颜色偏好更改为“甜菜”和“红色”:
pass1.favorite_food # => "beets"
查看您的附加代码,它看起来可以简化(AKA DRY'd AKA “Don't Repeat Yourself”)。我不使用 Windows,因此无法对此进行测试,但以下代码看起来是正确的:
def private_key
Dir.chdir('C:/OpenSSL/bin') do
system('openssl.exe')
system("genrsa -out C:/Sites/keys/#{@user}private.pem 2048")
end
end
def create_csr
Dir.chdir('C:/OpenSSL/bin') do
system('openssl.exe')
system("req -config c:/OpenSSL/openssl.cnf -new -batch -sha256 -key C:/Sites/keys/#{@username}private.pem -subj 'hal#{@user}' -out C:/Sites/keys/#{@username}csr.pem")
end
end
RubyDir.chdir
需要一个块,所以它会将目录更改为给定的参数,执行块中的命令,然后在退出时弹出目录。
而且,而不是打开管道,您应该能够使用system
看起来像它会完成您正在尝试做的事情。
可是等等!还有更多!
仍然有冗余,所以我会更干燥:
def create(cmd)
Dir.chdir('C:/OpenSSL/bin') do
system('openssl.exe')
system(cmd)
end
end
def private_key(u)
create("genrsa -out C:/Sites/keys/#{ u.user }private.pem 2048")
end
def create_csr(u)
create("req -config c:/OpenSSL/openssl.cnf -new -batch -sha256 -key C:/Sites/keys/#{ u.username }private.pem -subj 'hal#{ u.user }' -out C:/Sites/keys/#{@username}csr.pem")
end
这些方法不需要是您的 User 类的一部分,它们只知道如何访问用于从该类的实例中检索属性的方法。
将您的用户实例作为参数传递给任一方法,如果您的用户看起来像这样,这些方法将做正确的事情:
class User
attr_accessor :user, :username, :pass, :country
def initialize(user, username, pass, country=nil)
@user = user
@username = username
@pass = pass
@country = country
end
# ...more methods specific to users...
end
就像我说的,我没有 Windows,所以它未经测试,但它更接近 Ruby 代码应有的样子。