ruby - 类方法中的变量
问题描述
你能解释一下为什么attribute_accessors不能访问类变量吗?
当我在这里尝试在一个数组中列出所有子类的所有方法时,它的工作方式略有不同。它在每个子类中创建了数组@method_names,每个类都有特定的方法......所以我确实需要通过子类进行循环。
@method_names 是什么类型的变量/属性?
谢谢!
module First
class First_class
class << self
def info
puts "First_class method info."
puts @subclasses
puts @method_names
end
def inherited(subclass)
puts "#{subclass} located ..."
subclasses << subclass
end
def subclasses
@subclasses ||= []
end
def method_added(method_name)
puts "Method located #{method_name} ..."
method_names << method_name
end
def method_names
@method_names ||= []
end
end
def initialize
puts "Instance of First_class is created."
end
def first_method
end
end
class Second_class < First_class
def self.info
puts "Second_class method info."
puts @subclasses
puts @method_names
end
def second_method
end
def initialize
puts "Instance of Second_class is created."
end
end
class Third_class < First_class
def third_method
end
def initialize
puts "Instance of Third_class is created."
end
end
end
First::First_class.subclasses.each {
|subclass| puts subclass
subclass.method_names.each {
|methodn| puts methodn
}
}
################UPDATE######### 好吧,也许我把问题放错了。
基本上,如果我不创建对象实例,@@method_names(类变量)和@method_names(实例变量)有什么区别?在将更多输入插入@method_names 后,它仍会插入相同的object_id。那么@@method_names 有什么好处呢?
解决方案
更新以回答更新的问题。
ruby 中的类可以有类变量。但是,如果您修改类级别变量,所有实例都将被修改。不建议这样做,但会说明这一点。但也看到这个答案
class Foo
@@bar = 'bar'
attr_accessor :bar
def initialize
@bar = 'bar'
end
def class_bar
@@bar
end
def change_class_bar string
raise ArgumentError unless string.is_a?(String)
@@bar = string
end
end
a = Foo.new
b = Foo.new
# change the class variable @@bar
b.change_class_bar 'wtf?'
# see both instances are changed because objects are passed by referrence
print 'a.class_bar is: '
puts a.class_bar
print 'b.class_bar is: '
puts b.class_bar
# change one instance only
a.bar = 'only a has changed'
print 'a.bar is: '
puts a.bar
print 'b.bar is still: '
puts b.bar
运行这个,你应该得到输出:
a.class_bar is: wtf?
b.class_bar is: wtf?
a.bar is: only a has changed
b.bar is still: bar
原来的答案留在这里
@method_names
是实例化它的类的实例的实例变量。但是,除非这些属性是使用定义的 getter 或 setter 方法定义的,否则无法访问它以进行读/写。
ff = First::First_class.new
Instance of First_class is created.
=> #<First::First_class:0x00007fde5a6867b8>
ff.method_names
NoMethodError: undefined method `method_names' for #<First::First_class:0x00007fde5a6867b8>
Did you mean? methods
现在,如果您调用ff.methods
,您将看到通过标准 Ruby 继承定义的所有方法。
作为旁注,Ruby 中的类名通常使用PascalCase
参见PascalCase。Mixed_case
气馁。
推荐阅读
- javascript - 如何在php中获取已附加serializeArray的数组值
- php - 如何从命令终端获取网络流量并在 PHP 中显示
- react-native - Redux Persist,rehydrate 不能在 android 上工作
- entity-framework - 批量插入记录时,临时表在操作结束后不会删除,并且在第三个临时表处插入失败
- c++ - 如何在 cpp 中使用协议缓冲区存储大缓冲区/数组(char/int)...?
- reactjs - Express Js 如何作为项目的 devDependencies 工作
- javascript - 如何在单击按钮时删除多行
- openssl - 使用 api 的带有密码短语参数的 openssl 证书请求
- php - 使用 curl 在 null 响应时循环遍历数据
- python - 错误:413 请求太大 - 带有可恢复 MediaIoBaseUpload 请求的 Python Google Drive API