Ruby IRB 中的对象区分大小写
Ruby Object Case-Sensitive in IRB
所以我 运行 陷入了一个关于 object/receiver 个案例 (upper/lower) 的有趣困境。惯例规定小写,但似乎出了点问题。 但是,就我而言,我的代码仅在实例以上限开头时才有效?快把我逼疯了!
我正在使用带有 Ruby 的启动命令提示符。 IRB 2.3,还有 C9(问题也存在于 IDE)
一个例子:
#rex.rb
class Dog
def wants(something)
puts "Rex wants to #{something}."
end
end
#rex instance is lowercase, per convention and the book's fidelity
rex = Dog.new
rex.wants("play")
这个 运行s 在我的机器上(通过 ruby rex.rb)和 irb(通过 require "rex")也是如此。它 运行s。 但是,然后在irb中:
rex.wants("x") yields a NameError basically saying rex object is undefined.
为了解决这个问题,我必须修改代码:
#rex.rb
class Dog
def wants(something)
puts "Rex wants to #{something}."
end
end
#Rex starts with an uppercase R now, not lowercase r - which it should be
Rex = Dog.new
Rex.wants("play")
我 运行 在我的机器上(ruby rex.rb)和 irb(需要 "rex")也是如此。 然后,在 irb 中,
Rex.wants("x")
它 运行s (=> nil) 完美。
我的问题:为什么我必须将 object/receiver 的(第一个字母)大写? 惯例是它们以小写字母开头。
也许我正在使用的书 (Head First Into Rudy) 稍后会解决这个问题? IDK...这本书还没有触及 IRB。我只是想试验一下。希望其他受益的人...google 今天没有真正帮助我 ;(。
代码运行s...但是实例应该是小写的,不是吗?我在这里错过了什么?
有没有可能是我的机器坏了。当其他人测试它时,该代码片段在 ideone 上工作。但是它在我的机器和 c9 上对我来说失败了吗?我很茫然....
这里的问题是包含文件中定义的任何局部变量都将超出 IRB
的范围。通过定义常量,您可以解决这个问题。声明显式全局变量 $rex
或实例变量 @rex
是备选方案:
@rex = Dog.new
@rex.wants("play")
@rex 现在可以通过 IRB 访问...
@rex.wants "x"
# Rex wants to x.
# => nil
@John Hyland 对 declaring a constant within a module 提出了建议,您也可以考虑一下。
全局使用实例变量
@mudasobwa 对全局使用实例变量的异端指责并非没有道理。在 class 的上下文之外声明 @rex
并将包含的文件导入 IRB 会将那个实例变量添加到主对象。这违反了面向对象的设计原则,可能会造成混淆,一般应避免使用全局变量。
也就是说,如果出于实验目的将其视为 "fish out of water",则全局范围的实例变量可能是合适的。我更喜欢它而不是声明一个我们打算改变的常量。实例变量也可能更类似于您最终将部署的代码;通常在 rails
或 sinatra
应用程序中,实例变量在 view
可以访问的路由处理程序(例如 #get
)的范围内声明。
关于实例变量
传统上,实例变量应该属于它们所在的class。这是它的样子:
# dog.rb
class Dog
@@population = 0 # class variable (shared across all Dogs)
def initialize legs=4
@legs = legs # instance variable (for each Dog)
@@population += 1
end
def amputate
@legs-=1 if @legs > 0
@legs
end
# setters and getters (we could DRY this up with attr_accessor...)
def legs= x
@legs = x
end
def legs
@legs
end
def self.count
@@population
end
end
我们的 class 描述了狗在我们程序中的样子的 模型 。我们创建的每只狗都有自己的 实例变量 @legs
并共享一个 class 变量 @@population
所有的狗。调用 Dog.new
将调用 #initialize
,它默认将 @legs 设置为 4,并将总人口增加 1。从 irb,我们可以测试一下:
# irb terminal
rex = Dog.new.amputate
fido = Dog.new
puts "rex has %i legs, fido has %i legs" % [rex.legs, fido.legs]
# => rex has 3 legs, fido has 4 legs
puts "We have %i total dog(s)" % Dog.count
# => We have 2 total dog(s)
所以我 运行 陷入了一个关于 object/receiver 个案例 (upper/lower) 的有趣困境。惯例规定小写,但似乎出了点问题。 但是,就我而言,我的代码仅在实例以上限开头时才有效?快把我逼疯了!
我正在使用带有 Ruby 的启动命令提示符。 IRB 2.3,还有 C9(问题也存在于 IDE)
一个例子:
#rex.rb
class Dog
def wants(something)
puts "Rex wants to #{something}."
end
end
#rex instance is lowercase, per convention and the book's fidelity
rex = Dog.new
rex.wants("play")
这个 运行s 在我的机器上(通过 ruby rex.rb)和 irb(通过 require "rex")也是如此。它 运行s。 但是,然后在irb中:
rex.wants("x") yields a NameError basically saying rex object is undefined.
为了解决这个问题,我必须修改代码:
#rex.rb
class Dog
def wants(something)
puts "Rex wants to #{something}."
end
end
#Rex starts with an uppercase R now, not lowercase r - which it should be
Rex = Dog.new
Rex.wants("play")
我 运行 在我的机器上(ruby rex.rb)和 irb(需要 "rex")也是如此。 然后,在 irb 中,
Rex.wants("x")
它 运行s (=> nil) 完美。
我的问题:为什么我必须将 object/receiver 的(第一个字母)大写? 惯例是它们以小写字母开头。
也许我正在使用的书 (Head First Into Rudy) 稍后会解决这个问题? IDK...这本书还没有触及 IRB。我只是想试验一下。希望其他受益的人...google 今天没有真正帮助我 ;(。
代码运行s...但是实例应该是小写的,不是吗?我在这里错过了什么?
有没有可能是我的机器坏了。当其他人测试它时,该代码片段在 ideone 上工作。但是它在我的机器和 c9 上对我来说失败了吗?我很茫然....
这里的问题是包含文件中定义的任何局部变量都将超出 IRB
的范围。通过定义常量,您可以解决这个问题。声明显式全局变量 $rex
或实例变量 @rex
是备选方案:
@rex = Dog.new
@rex.wants("play")
@rex 现在可以通过 IRB 访问...
@rex.wants "x"
# Rex wants to x.
# => nil
@John Hyland 对 declaring a constant within a module 提出了建议,您也可以考虑一下。
全局使用实例变量
@mudasobwa 对全局使用实例变量的异端指责并非没有道理。在 class 的上下文之外声明 @rex
并将包含的文件导入 IRB 会将那个实例变量添加到主对象。这违反了面向对象的设计原则,可能会造成混淆,一般应避免使用全局变量。
也就是说,如果出于实验目的将其视为 "fish out of water",则全局范围的实例变量可能是合适的。我更喜欢它而不是声明一个我们打算改变的常量。实例变量也可能更类似于您最终将部署的代码;通常在 rails
或 sinatra
应用程序中,实例变量在 view
可以访问的路由处理程序(例如 #get
)的范围内声明。
关于实例变量
传统上,实例变量应该属于它们所在的class。这是它的样子:
# dog.rb
class Dog
@@population = 0 # class variable (shared across all Dogs)
def initialize legs=4
@legs = legs # instance variable (for each Dog)
@@population += 1
end
def amputate
@legs-=1 if @legs > 0
@legs
end
# setters and getters (we could DRY this up with attr_accessor...)
def legs= x
@legs = x
end
def legs
@legs
end
def self.count
@@population
end
end
我们的 class 描述了狗在我们程序中的样子的 模型 。我们创建的每只狗都有自己的 实例变量 @legs
并共享一个 class 变量 @@population
所有的狗。调用 Dog.new
将调用 #initialize
,它默认将 @legs 设置为 4,并将总人口增加 1。从 irb,我们可以测试一下:
# irb terminal
rex = Dog.new.amputate
fido = Dog.new
puts "rex has %i legs, fido has %i legs" % [rex.legs, fido.legs]
# => rex has 3 legs, fido has 4 legs
puts "We have %i total dog(s)" % Dog.count
# => We have 2 total dog(s)