In Ruby, How to Check If Method "Foo=()" Is Defined

In Ruby, how do I check if method foo=() is defined?

The problem is that the foo= method is designed to be used in assignments. You can use defined? in the following way to see what's going on:

defined?(self.foo=())
#=> nil
defined?(self.foo = "bar")
#=> nil

def foo=(bar)
end

defined?(self.foo=())
#=> "assignment"
defined?(self.foo = "bar")
#=> "assignment"

Compare that to:

def foo
end

defined?(foo)
#=> "method"

To test if the foo= method is defined, you should use respond_to? instead:

respond_to?(:foo=)
#=> false

def foo=(bar)
end

respond_to?(:foo=)
#=> true

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

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).

How to check if private method is defined in ruby

You want Module#private_method_defined?.

class Foo
def do_stuff_if_bar_is_defined
if self.class.private_method_defined?(:bar)
do_stuff
end
end

private

def bar
"bar"
end

private_method_defined? :bar #=> true
end
Foo.private_method_defined? :bar #=> true

How to determine the class a method was defined in?

What about this?

class A
def foo
puts "I was defined in #{Module.nesting.first}"
end
end

class B < A
def foo
puts "I was defined in #{Module.nesting.first}"
super
end
end

Corrected following WandMaker's suggestion.

Does assert_not_nil foo == assert defined? foo in Ruby's Test::Unit?

nil is a value, so a variable who's value is nil is defined. Here's some repl output to demonstrate:

[1] pry(main)> a = nil
=> nil
[2] pry(main)> defined? a
=> "local-variable"
[3] pry(main)> defined? b
=> nil

You may be confused because accessing an undefined instance variable also returns nil, but that's still not the same:

[4] pry(main)> defined? @b
=> nil
[5] pry(main)> @b = nil
=> nil
[6] pry(main)> defined? @b
=> "instance-variable"

Global variables ($foo) work like instance variables in this respect, but accessing an uninitialized class variable (@@bar) raises NameError.

One last thing: local variables are declared at parse time in Ruby, so if any branch of your method sets a local, that local is defined (and initialized to nil) anywhere in the method (or block).

Checking if a variable is defined?

Use the defined? keyword (documentation). It will return a String with the kind of the item, or nil if it doesn’t exist.

>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"

As skalee commented: "It is worth noting that variable which is set to nil is initialized."

>> n = nil  
>> defined? n
=> "local-variable"


Related Topics



Leave a reply



Submit