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!

···

--
Posted via http://www.ruby-forum.com/.

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

···

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

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!

Hi --

···

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

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.

You need the 'self.' part because class is a keyword. It's a bit
verbose but something's got to give :slight_smile:

David

--
Rails training from David A. Black and Ruby Power and Light:
   ADVANCING WITH RAILS April 14-17 New York City
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!

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

···

--
Posted via http://www.ruby-forum.com/.

Ryan Davis ,
"When you want to have a class call an "instance method", which instance
would call it?"

Good point! Makes sense.

Anurag Priyam, 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?

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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?

···

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?

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.

···

--
Anurag Priyam
http://about.me/yeban/

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 Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

On Wed, Feb 23, 2011 at 07:40, marco antonio f. <marcofognog@gmail.com> wrote:

Ryan Davis ,
"When you want to have a class call an "instance method", which instance
would call it?"

Good point! Makes sense.

Anurag Priyam, 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?

--
Posted via http://www.ruby-forum.com/\.

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

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.

···

--
Anurag Priyam
http://about.me/yeban/