如何打印一个对象可以访问到的 instance_variables? 1、包含自己的实例变量。 2、包含继承来的实例变量。
目前找了一些资料没有找到怎么打印继承来的实例变量,这样导致无法观察整个对象的信息。
比如你的实例 叫 instance
instance.class.ancestors.each {|klass| puts klass.instance_variables}
Ruby 和 Rails 貌似找不到直接的方法,不过可以尝试在底层的 class 里面定义一个方法,用当前 class 的所有实例变量减去 superclass 里面的所有实例变量,这样就获取到了 当前 class 里面定义的实例变量了。如果两个 class 之间有重合的实例变量就是继承过来的
Example
class Base
def initialize
@base = "base"
end
def current_class_instance_variables
instance_variables - self.class.superclass.new.instance_variables
end
def current_class_inherited_instance_variables
self.class.superclass.new.instance_variables & instance_variables
end
end
class Application < Base
def initialize()
super
@application = "application"
end
end
class Post < Application
def initialize()
super
@post = "post"
end
end
class Article < Application
def initialize()
super
@article = "article"
end
end
Article.new.current_class_instance_variables
Post.new.current_class_instance_variables
Application.new.current_class_instance_variables
Base.new.current_class_instance_variables
Article.new.current_class_inherited_instance_variables
Post.new.current_class_inherited_instance_variables
Application.new.current_class_inherited_instance_variables
Base.new.current_class_inherited_instance_variables
输出结果如下
但是这样也有很多问题解决不了,比如在某个方法里面添加的实例变量,继承了一些抽象类之类或者实例变量被重写了的问题。
我和 3 楼理解的一样,实例变量不会被继承,只能通过这些奇技淫巧来处理
原始需求是这样的:实例对象访问一些 ancestors 不是属于自己类里定义的,实例类继承链上的类又动态 include 很多内容。最终使用实例的时候看到到处访问一些属性。debug 的时候就想 pp 完这个实例类继承链上的所有可以访问的实例属性。代码里有很多访问是父类的东西,如果不知道实例类可以访问所有的属性的话,看代码起来就比较奇怪,缺少对类的全局认识。 如果能 pp 完这个类的所有可以访问的属性,就对这个类有了全局认识。
最近在使用https://github.com/Arachni/arachni/这个框架,由于里面的动态定义太多了。调试的时候需要观察的东西比较多,如实例可以访问到的属性,实例方法。 同时又发现太多回调的使用,已经形成地狱回调了。一些奇怪的原始需求都是来自这个框架的使用。
最终使用实例的时候看到到处访问一些属性
你看到的"属性"并不是实例变量,而是方法。
ruby 语言中并不太常用"属性"一词。代码中看到的形如 obj.size, obj.price 均为方法调用。而实例变量的访问,要么是在对象内部通过 @var_name 直接访问,要么是在外部通过 instance_variable_get, instance_exec 这样的代码探针来调用。
所以你需要的可能是 obj.methods 来返回所有的非私有方法