Forum: Ruby on Rails Modifying a class method's state

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Nick (Guest)
on 2008-10-24 00:04
(Received via mailing list)
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
Kazim Z. (Guest)
on 2008-10-24 01:01
(Received via mailing list)
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
....


--
- Kazim Z.
Blog: http://tuxplayground.blogspot.com
Nick (Guest)
on 2008-10-24 19:02
(Received via mailing list)
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
This topic is locked and can not be replied to.