Use of self in a class

To Everyone,

Thanks for your help.

When you are confused about something, it is sometimes hard to distill
all your thoughts down to the essence of the issue and ask the right
question. But I am trying to define a CONSTANT using the result of an
instance method and Ruby just doesn't allow that and I don't understand
why.

Why does it have to be a class method? Is it because a constant is
"class-only". It can't be accessed by an instance. You could define an
instance method that would return the same information as the constant
but there is no syntax to access the constant directly from an instance
object.

So to define a constant, I can use a literal or a class method but not
an instance method. And it can only be accessed via Class::Constant.

Buzz

Hi --

Marnen Laibow-Koser wrote:

When you are confused about something, it is sometimes hard to distill
all your thoughts down to the essence of the issue and ask the right
question. But I am trying to define a CONSTANT using the result of an
instance method

No you're not. The constant you're trying to define is clearly a class
property.

If you think about it, this is as it should be. The constant is going
to have the same value for every instance of the class. In other words:

a = PaymentType.new
b = PaymentType.new

a and b are now separate instances of PaymentType -- but surely you
never want a.PAYMENT_TYPES to be different from b.PAYMENT_TYPES ?

The syntax of a.PAYMENT_TYPES won't work. I am not sure if you meant it
to work or you were just using it for the sake of explanation.

The syntax will work if you've got an instance method called
PAYMENT_TYPES, but if you don't, it will fail -- whether or not you
have a constant called PAYMENT_TYPES.

But I get your point, which has enhanced my understanding. Things that
relate to the class in general, things that shouldn't be redefined, like
Math:PI are controlled only by class methods. So, in the above example,
if the payment_types were to change dynamically as the program executed,
I would not use a constant, I would setup getter and setter methods.

I think you're overthinking it. There's no inherent connection between
constants and class methods.

   module MyMathModule
     PI = 3.14159265358979
   end

   puts "PI is #{MyMathModule::PI}"

I've created a module and a constant inside that module. The constant
is resolved using the :: operator, and no methods are involved.

If you define an instance method, you can use the class's constants:

class Rainbow
   COLORS = %w{ red orange yellow green blue indigo violet }

   def show_me_the_colors
     puts "My colors are: #{COLORS.join(", ")}"
   end
end

r = Rainbow.new
r.show_me_the_colors

   => My colors are: red, orange, yellow, green, blue, indigo, violet

David

I was going to say that defining a class constant like this,
initialized by an expression evaluated when the class definition is
executed is normally the way to go.

But then I went back an looked at the post at the beginning of this
thread, and looked at the code, which when rewritten to look something
like this:

  def self.get_payment_types
   payment_types_all = find(:all, :select => "display_name,
stored_name" , :order => :display_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 = find(:all, :select => "display_name, stored_name" ,
:order => :display_name)..map {|item| [item.display_name,
item.stored_name]}

And note that since we are really getting the payment types from the
database, a constant might not be the right path.

If the payment types can change over time, then it's not a constant.

If it is a constant maybe the database isn't the best place to save it.

Thanks again to everyone for your help.

I keep reading over this thread and appreciating the things being
explained to me. I have gained a better understanding of the separation
of class things and instance things. I just need to keep studying.

Buzz

I was addressing myself at this point to the general matter of
constant scope, visibility, and syntax, which I think was an
impediment to analyzing the underlying problem.

David