Calling class method from instance method

Pretty dumb question – how do I call a class method from inside an
instance method (of the same class)?

The use case I have is that in an activerecord model class, I would like
to define an instance method which calls find_by_sql.

I have tried and found that this works:
self.class.find_by_sql

But this seems pretty verbose for something so obvious.

Thanks!

On Monday 07 April 2008, Yu-shan Fung wrote:

But this seems pretty verbose for something so obvious.

Thanks!

You can replace self.class with the name of the class. For example:

class C

def C.x
end

def y
self.class.x
C.x
end

end

There’s a difference, however. If you derive a class from C and override
C.x
from D:

class D < C
def self.x
end
end

using self.class.x from C#y will use the version of x defined in the
instance’s class (that is, C.x if called by an instance of C and D.x if
called
by an instance of D). Using C.x will, obviously, always call C.x. Here’s
some
code which demonstrates this:

class C
def self.x
puts “x of C”
end

def y
self.class.x
end

def z
C.x
end
end

class D < C
def self.x
puts “x of D”
end
end

puts “Calling y on an instance of C”
C.new.y
puts “Calling y on an instance of D”
D.new.y
puts “Calling z on an instance of D”
D.new.z

I hope this helps

Stefano

Hi –

On Mon, 7 Apr 2008, Yu-shan Fung wrote:

But this seems pretty verbose for something so obvious.
You need the ‘self.’ part because class is a keyword. It’s a bit
verbose but something’s got to give :slight_smile:

David

Is it possible to do the opposite? call a instance method from a class
method?

On Feb 22, 2011, at 17:44 , marco antonio f. wrote:

Is it possible to do the opposite? call a instance method from a class
method?

When you have an instance “call a class method” you’re really having the
instance ask the class (an instance of Class) to call it’s method.

When you want to have a class call an “instance method”, which instance
would call it?

Is it possible to do the opposite? call a instance method from a class
method?

Create an instance and call the instance method; very weird usage
though. Why would you need it?

class Foo
def self.hello
Foo.new.hello
end

def hello
puts “Hello World”
end
end

You can basically call any method from anywhere if you have the right
receiver.

First, write your class method so that it accepts an instance:

==== begin snippet ====
class ExtendedFile
attr_accessor :filename

def self.process(file)
if file.exists?
# do some work
end
end

def exists?
self.exists? self.filename
end
end
==== end snippet ====

Of course, once you can do that, then you can refactor the class
method into an instance method. Delete the method’s argument and
replace it with a reference to self:

==== begin snippet ====
class ExtendedFile
attr_accessor :filename

def process # now it’s an instance method
if self.exists? # reference self instead of the argument
# do some work
end
end

def exists?
self.exists? self.filename
end
end
==== end snippet ====

~ jf

John F.
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

#I dont want to define a nother class method exactly the same as the
already declared instance method.
end

Since file_exists? is an instance method, it is very likely to return
true/false based on the state of the instance (see below). Calling
file_exists in self.method does not make sense unless its
responsibility is to act on an instance of your class - like a
factory, or processing an instance passed to it as a parameter.

def self.method(object)
if object.file_exists?
# do something on that object
object.statistics
end
end

or,

def self.create(*args)
object = SomeClass.new(*args)
return object if object.file_exists?
end

def file_exists?
#there are instance methods depending on this one
File.exists?(“some_file_name.txt”)
end

Umm, is the file name hard coded, or does it depend on the state of
the instance, like:

def file_exists?
File.exists?(@file)
end

If it is hard coded, or depends on a constant, you might as well
define a class method:

class SomeClass
CONFIG = “~/.foo.rc”

def self.config_exists?
File.exists?(CONFIG)
end

def init
raise “Config file not found” unless SomeClass.config_exists?

end
end

end

How do you deal with this kind of thing?

Depends on the context.

Thanks for the replies.

Turned out it was a matter of code organization. The methods I needed to
call, I put in another class, and called from its instances.

regards

Ryan D. ,
“When you want to have a class call an “instance method”, which instance
would call it?”

Good point! Makes sense.

Anurag P., this is pretty wierd… but works.

You see, there’s stuff that need to be donne in both cases, in instances
and in classes. For example:

class SomeClass
def self.method
if file_exists?
#do stuff
end
#something need to be donne here, and I need to check if the file
exists
#I dont want to define a nother class method exactly the same as the
already declared instance method.
end

def file_exists?
#there are instance methods depending on this one
File.exists?(“some_file_name.txt”)
end
end

How do you deal with this kind of thing?