Given a Class, See If Instance Has Method (Ruby)

Given a class, see if instance has method (Ruby)

I don't know why everyone is suggesting you should be using instance_methods and include? when method_defined? does the job.

class Test
def hello; end
end

Test.method_defined? :hello #=> true

NOTE

In case you are coming to Ruby from another OO language OR you think that method_defined means ONLY methods that you defined explicitly with:

def my_method
end

then read this:

In Ruby, a property (attribute) on your model is basically a method also. So method_defined? will also return true for properties, not just methods.

For example:

Given an instance of a class that has a String attribute first_name:

<instance>.first_name.class #=> String

<instance>.class.method_defined?(:first_name) #=> true

since first_name is both an attribute and a method (and a string of type String).

checking if a method is defined on the class

Use this:

C.instance_methods(false).include?(:a)
C.instance_methods(false).include?(:b)
C.instance_methods(false).include?(:c)

The method instance_methods return an Array of methods that an instance of this class would have. Passing false as first parameter returns only methods of this class, not methods of super classes.

So C.instance_methods(false) returns the list of methods defined by C.

Then you just have to check if that method is in the returned Array (this is what the include? calls do).

See docs

Ruby: check if object has a method with particular signature, like respond_to?

Simplest thing to do is try it and rescue the ArgumentError.

begin
thing.make(env: @@__ENV__, apiKey: "myKey")
rescue ArgumentError => e
...guess not...
end

You can also introspect the parameters of the Method object. This returns an Array of Arrays like [[:key, :env], [:key, :apiKey]] . You're looking for :key if its optional, :keyreq if it's required.

params = thing.method(:make).parameters
p [:env,:apiKey].all? { |arg|
params.include?([:key,arg]) || params.include?([:keyreq, arg])
}

If you have to do this as part of application code, you may want to reconsider your design.

How do I check if a variable is an instance of a class?

It's almost exactly the same. You can use Object's instance_of? method:

"a".instance_of? String # => true
"a".instance_of? Object # => false

Ruby also has the is_a? and kind_of? methods (these 2 are aliases, and work exactly the same), which returns true is one of the superclasses matches:

"a".is_a? String # => true
"a".is_a? Object # => true

How to test in Ruby/Rails if method has been called in class body?

It's usually recommended to test the behavior, not the implementation. In this case, whatever acts_as_paranoid provides for this class in terms of behavior, is what you want to test.

However, if you trust that calling acts_as_paranoid correctly provides all the behavior you need and just want to test that it is added to the class, you can use:

assert User.included_modules.include? ActsAsParanoid::Core

To figure this out I just briefly looked at the source code for acts_as_paranoid here: https://github.com/ActsAsParanoid/acts_as_paranoid/blob/master/lib/acts_as_paranoid.rb#L8

You can see that on line 50, it extends the ActsAsParanoid module to ActiveRecord::Base, which gives the model classes access to the acts_as_paranoid method. And if you look at the definition of this method, you can see it calls include ActsAsParanoid::Core

Checking for an instance method

Yes, you can use

 method_defined?

,which is class method to check whether particular class has instance method defined or not.
Following link will explain you more

Given a class, see if instance has method (Ruby)

Testing a ruby module class method not working

Reading the reference in this article which explains include, extend, and prepend and I found out that extends works with the Singleton class already so the self is unnecesary.

I made a small test with this code, which removes the self in the definition

module SomeModule
module Account
def account_info
raise NotImplementedError
end
end
end

class MockClass
extend SomeModule::Account
end

MockClass.account_info

And that raises NotImplementedError



Related Topics



Leave a reply



Submit