How do I introspect things in Ruby?
Sure, it's even simpler than in Python. Depending on what information you're looking for, try:
obj.methods
and if you want just the methods defined for obj (as opposed to getting methods on Object
as well)
obj.methods - Object.methods
Also interesting is doing stuff like:
obj.methods.grep /to_/
To get instance variables, do this:
obj.instance_variables
and for class variables:
obj.class_variables
Ruby method introspection
There is an established format for these things. You can modify the following to meet your needs.
class Object
def argument_count m; method(m).arity end
def argument_names m; method(m).parameters end
end
Greeter.argument_count(:greet) # => -2
Greeter.argument_names(:greet) # => [[:req, :name], [:opt, :weekday]]
How do you list the currently available objects in the current scope in ruby?
ObjectSpace.each_object could be what you are looking for.
To get a list of included modules you could use Module.included_modules.
You can also check if an object responds to a method on a case-by-case basis using object.respond_to?.
How do I inspect the methods of a Ruby object?
methods
takes an optional boolean parameter, which specifies whether to also list the methods from the object's class and its superclasses or just the object's singleton methods. So you can do obj.methods(false)
to only get the singleton methods defined on obj
.
If you want the methods defined by the object's class, but not those defined by its superclasses, you can get that by calling instance_methods(false)
on the object's class, so it's obj.class.instance_methods(false)
.
Ruby: Get list of different properties between objects
needs some tweaking, but here's the basic idea:
module CompareIV
def compare(other)
h = {}
self.instance_variables.each do |iv|
print iv
a, b = self.instance_variable_get(iv), other.instance_variable_get(iv)
h[iv] = b if a != b
end
return h
end
end
class A
include CompareIV
attr_accessor :foo, :bar, :baz
def initialize(foo, bar, baz)
@foo = foo
@bar = bar
@baz = baz
end
end
a = A.new(foo = 1, bar = 2, baz = 3)
b = A.new(foo = 1, bar = 3, baz = 4)
p a.compare(b)
A better way to introspect a capture
A better way to introspect ...
In general, a better way to do anything in any programming language is to not introspect if you can avoid it.
In general, in Raku, you can avoid manual introspection. See the section Introspection toward the end of this answer for further discussion.
... a capture
The best tool for getting the functionality that introspection of a capture provides is to use a signature. That's their main purpose in life.
I want to test the type of the first object in a signature
Use signatures:
proto handle(|) {*}
multi handle( Pod $node ) { ... }
multi handle( Str $string ) { ... }
multi handle( Nil ) { ... }
The following shows some ways I have found that work.
While they do what you want, they are essentially ignoring all of Raku's signature features. They reduce the signature to just a binding to the capture as a single structure; and then use manual introspection of that capture in the routine's body.
There's almost always a simpler and better way to do such things using signatures.
why does [
|c[0].WHAT ~~ Rat
, withc[0] == 3/2
] not work?
I'll simplify first, then end up with what your code is doing:
say 3/2 ~~ Rat; # True
say (3/2) ~~ Rat; # True
say (3/2).WHAT ~~ Rat; # True
say |((3/2).WHAT ~~ Rat); # True
say (|(3/2).WHAT) ~~ Rat; # False
say |(3/2).WHAT ~~ Rat; # False
The last case is because |
has a higher precedence than ~~
.
Is there a better way than stringifying and testing for the string equivalent of the Type?
OMG yes.
Use the types, Luke.
(And in your use case, do so using signatures.)
Introspection
Compared to code that manually introspects incoming data in the body of a routine, appropriate use of signatures will typically:
Read better;
Generate better low-level code;
Be partially or fully evaluated during the compile phase.
If a language and its compiler have addressed a use case by providing a particular feature, such as signatures, then using that feature instead of introspection will generally lead to the above three benefits.
Languages/compilers can be broken into four categories, namely those that:
Do not do or allow any introspection;
Allow the compiler to introspect, but not devs;
Allow both the compiler and devs to introspect, but aim to make it a last resort, at least for devs;
Enable and encourage devs to introspect.
Raku(do) are in the third category. In the context of this SO, signatures are the primary feature that all but eliminates any need for a dev to manually introspect.
Fastest/One-liner way to list attr_accessors in Ruby?
There is no way (one-liner or otherwise) to list all methods defined by attr_accessor and only methods defined by attr_accessor without defining your own attr_accessor.
Here's a solution that overrides attr_accessor in MyBaseClass to remember which methods have been created using attr_accessor:
class MyBaseClass
def self.attr_accessor(*vars)
@attributes ||= []
@attributes.concat vars
super(*vars)
end
def self.attributes
@attributes
end
def attributes
self.class.attributes
end
end
class SubClass < MyBaseClass
attr_accessor :id, :title, :body
end
SubClass.new.attributes.inspect #=> [:id, :title, :body]
How to get activerecord associations via reflection
Model.reflections
gives information about a model's associations. It is a Hash
keyed on the association name. e.g.
Post.reflections.keys # => ["comments"]
Here is an example of some of the information it can be used to access:
Post.reflections["comments"].table_name # => "comments"
Post.reflections["comments"].macro # => :has_many
Post.reflections["comments"].foreign_key # => "message_id"
Note: this answer has been updated to cover Rails 4.2 based on MCB's answer and the comments below. In earlier versions of Rails the reflection's foreign_key
was accessed using primary_key_name
instead, and the keys for the reflections may be symbols instead of strings depending on how the association was defined e.g. :comments
instead of "comments"
.
Related Topics
Respond_To' VS. 'Respond_To_Missing'
Rails Console Running Incredibly Slowly When Editing Text
How to Write Specs for Code That Depends on Environment Variables
Augmenting a Model from an External Gem
Adding a Method to Built-In Class in Rails App
How Does Rails Implement Before_Filter
Ruby on Rails 3 - Public Live Chat
Ruby: Cannot Parse Excel File Exported as CSV in Os X
How to Check from Ruby Whether a Process with a Certain Pid Is Running
How to Create a Rest API for a Ruby Application
How to Force Activerecord to Reload a Class
Ruby: How to Count the Number of Times a String Appears in Another String
Using Typeahead from Twitter Bootstrap in a Form (Formtastic)
Converting an Array of Keys and an Array of Values into a Hash in Ruby
Creating an Md5 Hash of a Number, String, Array, or Hash in Ruby