Modifying a class method's state


#1

Hi guys. I’m experiencing some strange behaviour in my Rails app. I
have a constant, and two class methods:

#----------#
COORDINATES_NOT_NULL_SQL =
‘latitude IS NOT NULL and longitude IS NOT NULL’

def self.sql_for_non_null_coordinates
COORDINATES_NOT_NULL_SQL
end

def self.filtered_properties(params)
conditions_string = self.sql_for_non_null_coordinates
…8<…
conditions_string << ’ AND ’ << filtered[:sql]
…8<…
end
#----------#

If I call #filtered_properties multiple times in a row, the value that
#sql_for_non_null_coordinates returns changes:
http://pastie.org/299037

This line is causing the change:
conditions_string = self.sql_for_non_null_coordinates
But why? And is it possible to prevent this behaviour?

Thanks,
Nick


#2

On Thu, Oct 23, 2008 at 10:35 PM, Nick removed_email_address@domain.invalid wrote:

end
#sql_for_non_null_coordinates returns changes:
http://pastie.org/299037

This line is causing the change:
conditions_string = self.sql_for_non_null_coordinates
But why? And is it possible to prevent this behaviour?

Hi Nick,
This is because Ruby constants are not constants. They can change.
Ruby warns you when you reinitialize a constant, but not otherwise.
That is,
Constant << “anything”
won’t produce a warning.

You should use something like,
conditions_string = self.sql_for_non_null_coordinates.dup


#3

On Oct 23, 1:30 pm, “Kazim Z.” removed_email_address@domain.invalid wrote:

Hi Nick,
This is because Ruby constants are not constants. They can change.
Ruby warns you when you reinitialize a constant, but not otherwise.
That is,
Constant << “anything”
won’t produce a warning.

You should use something like,
conditions_string = self.sql_for_non_null_coordinates.dup

Thanks for the tip, Kazim! That answers my question perfectly.

Cheers,
Nick