Use of self in a class

class PaymentType < ActiveRecord::Base

def self.get_payment_types
payment_types_all = find(:all, :select => "display_name,
stored_name" , :order => :display_name)
# Creates a nested array of [[display_name,
stored_name],[display_name, stored_name]]
payment_types = payment_types_all.map {|item| [item.display_name,
item.stored_name]}
end

# must be defined after the method. Can't be defined in a method
PAYMENT_TYPES = get_payment_types

end

Here is some code that works fine, but I don't understand the need for
the self reference in the def, I will get an undefined variable or
method error.

in a nutshell def self.get_payment_types tells ruby to make a class
method (which is basically a single method on the class object, ie
self) rather than an instance method.

Fred

In other words, you just use def get_payment_types if
get_payment_types is to be performed on a specific instance of that
class, and def self.get_payment_types if it is just a generic function
for that class...

E.g.

def get_payment_types
  ...
end

pt = PaymentType.new
pt_types = pt.get_payment_types

-or-

def self.get_payment_types
  ...
end

pt_types = PaymentType.get_payment_types

JangoSteve wrote:

In other words, you just use def get_payment_types if
get_payment_types is to be performed on a specific instance of that
class, and def self.get_payment_types if it is just a generic function
for that class...

I guess what I am confused about is this:

Dave Thomas talks about self as a special variable used by Ruby to
maintain a reference to the context of where the interpreter is
operating and any given point, so it knows where to find a particular
method. So why does Ruby not seem to know the context of
"get_payment_types" without the self. Here is a slight variation on the
previous code:

class PaymentType

    def self.get_payment_types
       puts "Master Self is set to: " + self.to_s + " 1"
       puts
       payment_types = ["Check", "Credit Card", "Purchase Order"]

    end

  # must be defined after the method. Can't be defined in a method

     PAYMENT_TYPES = get_payment_types
     p(PAYMENT_TYPES); puts
     puts "Master Self is set to: " + self.to_s + " 2"
     puts

end

puts "Master Self is set to: " + self.to_s + " 3"
puts
p(PaymentType::PAYMENT_TYPES << self.to_s)
puts
puts "Master Self is set to: " + self.to_s + " 4"

This is an attempt to show the context contained in "self" at various
points.
You will see it change as the interpreter executes the code
sequentially. As it executes in the class, Ruby understands the context.
So, it knows it is in the class, so why can't I call on a method without
the self reference. When a call comes in from a browser, Rails starts
executing inside a controller class, calling it's methods who in turn
call on each other within the same class, all of which typically won't
have the self reference. I am trying to get at some fundamental issue of
object-oriented programming that I am don't understand.

Hi --

JangoSteve wrote:

In other words, you just use def get_payment_types if
get_payment_types is to be performed on a specific instance of that
class, and def self.get_payment_types if it is just a generic function
for that class...

I guess what I am confused about is this:

Dave Thomas talks about self as a special variable used by Ruby to
maintain a reference to the context of where the interpreter is
operating and any given point, so it knows where to find a particular
method. So why does Ruby not seem to know the context of
"get_payment_types" without the self. Here is a slight variation on the
previous code:

I think you're confusing defining a method with calling a method. self
always serves as the default receiver for messages -- meaning that
this:

   my_method(a,b,c)

is interpreted as this:

   self.my_method(a,b,c)

When you're defining a method, if you designate a specific object for
the method, like this:

   def my_object.some_method(a,b,c)
     # ...
   end

then the method will be a singleton method on that object -- meaning
that the method is available only to that object.

So when you do this:

   class Something
     def self.greet
       puts "Hello from #{self}!"
     end
   end

you're defining a method on the object self -- which happens to be, at
that point in execution, the class object Something.

There's a bit more to it, but am I on the right track, in terms of
what you're finding confusing?

David

So when you do this:

   class Something
     def self.greet
       puts "Hello from #{self}!"
     end
   end

you're defining a method on the object self -- which happens
to be, at that point in execution, the class object
Something.

And just to beat the horse a little more, that is equivalent to writing:

  class Something
    def Something.greet
      puts "Hello from #{self]"
    end
  end

In both cases you call the method on the class object itself (e.g., Something.greet).

I'm not sure whether there are subtle differences between those two idioms--it seems like the self.greet formulation is more common (at least in the rails world). I think the other one is clearer, personally.

GHC Confidentiality Statement

This message and any attached files might contain confidential information protected by federal and state law. The information is intended only for the use of the individual(s) or entities originally named as addressees. The improper disclosure of such information may be subject to civil or criminal penalties. If this message reached you in error, please contact the sender and destroy this message. Disclosing, copying, forwarding, or distributing the information by unauthorized individuals or entities is strictly prohibited by law.

# Inside a class definition self is the class itself
   # Note that another equivalent def statement would be