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
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
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 ====
#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
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?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.