我显然很擅长Ruby,而且编程一般,非常感谢任何帮助。
这是我的代码段:
class Player
attr_accessor :name, :hp
def initialize(name, hp)
@name = name
@hp = hp
end
def name
@name
end
def hp
@hp
end
end
def prompt
print "> "
end
prompt; pname = gets.chomp
player = Player.new(pname, rand(20..30))
puts "#{player.name} \:\: #{player.hp} HP"
def test
puts "#{player.name} \:\: #{player.hp} HP - IN METHOD"
end
test
运行时,结果如下:
$ ruby wtf.rb
> Test Name
Test Name :: 20 HP
wtf.rb:24:in `test': undefined local variable or method `player' for main:Object (NameError) from wtf.rb:27:in `<main>'
为什么我的通话工作在第一个实例,而不是第二个?是因为它现在正在寻找一个新的&#34;播放器&#34; &#34;测试&#34;中的变量方法?如果是这样,我如何从之前创建的类实例中调用它?
谢谢!
答案 0 :(得分:1)
player
被定义为方法test
范围之外的局部变量,
将player
的引用更改为@player
,使其成为实例变量
以下是范围和变量的快速reference,以及similar question
作为旁注,您不应将test
用作方法名称,因为它已在Kernel上定义
irb(main):001:0> method(:test)
=> #<Method: Object(Kernel)#test>
答案 1 :(得分:0)
def test
puts "#{player.name} \:\: #{player.hp} HP - IN METHOD"
end
您忘记将player
传递给方法:
def test(player)
puts "#{player.name} \:\: #{player.hp} HP - IN METHOD"
end
test(player) # => player = Player.new(pname, rand(20..30)) :: 22 HP - IN METHOD
答案 2 :(得分:0)
Ruby没有像Javascript这样的函数的词法范围,所以这个(ruby):
player = Player.new(pname, rand(20..30))
def test
# error: undefined variable or method 'player',
# this happens because player was defined
# in an unrelated scope outside this method
puts "#{player.name} \:\: #{player.hp} HP - IN METHOD"
end
test
NOT 等效于此(javascript)
var player = new Player(pname, ...);
var test = function() {
# works as expected, player is available because it was defined
# in the parent scope
console.log(player.name + "\:\:" + player.hp + " HP - IN METHOD");
};
test();
如果你想在ruby上使用类似于词法范围的东西,也许你应该使用lambda
player = Player.new(pname, rand(20..30))
test = lambda do
# works as expected, this block scope inherits from parent scope where the block
# was created, so, it can access player local variable
puts "#{player.name} \:\: #{player.hp} HP - IN METHOD"
end
test.call