Ruby:如何不实例化类,访问类方法中的实例变量?
解决Ruby类方法中变量的外部访问问题
首先得明确一个关键知识点:你在类方法里定义的@starting和@finished,不是普通的实例变量,而是属于Run这个类本身的「类实例变量」(因为Ruby里类本身也是一个对象)。你原来添加的attr_accessor :starting, :finished是给Run的实例对象(也就是Run.new创建出来的对象)生成getter/setter方法的,和类方法里的类实例变量完全不相关,这就是你无法直接访问的原因。
不用实例化类也能访问这些变量,有两种常见方案:
方案一:给类添加类级别的访问器
你可以通过class << self块来给类本身定义attr_accessor,这样生成的getter/setter就是类级别的,能直接通过类名调用。不过要注意:你原来的类方法名和变量名重名了(比如def self.starting和attr_accessor :starting),这会导致递归调用栈溢出,所以得把类方法改名,比如改成start和finish:
class Run # 给类本身定义访问器 class << self attr_accessor :starting, :finished end def self.start print "starting..." self.starting = true self.finished = false end def self.finish print "finished!" self.starting = false self.finished = true end end
现在你就可以这样调用了:
Run.start puts Run.starting # 输出 true puts Run.finished # 输出 false Run.finish puts Run.starting # 输出 false puts Run.finished # 输出 true
方案二:手动定义类级别的getter方法
如果你不想改动类方法的名字,也可以直接给类添加专门的getter方法来暴露这些类实例变量:
class Run def self.starting print "starting..." @starting = true @finished = false end def self.finished print "finished!" @starting = false @finished = true end # 定义类级别的getter方法 def self.get_starting @starting end def self.get_finished @finished end end
调用方式:
Run.starting puts Run.get_starting # 输出 true Run.finished puts Run.get_finished # 输出 true
为什么原来的写法不行?
再强调一下:普通的attr_accessor生成的方法是给Run的实例对象用的,比如:
run_instance = Run.new run_instance.starting = true puts run_instance.starting
而你在类方法里操作的@starting是属于Run这个类对象的变量,和实例对象的变量完全是两个独立的东西,所以原来的attr_accessor根本管不到类实例变量,自然无法通过Run.finished访问。
内容的提问来源于stack exchange,提问作者Domani Tomlindo
相关产品推荐
相关产品推荐

