P
Peter Lacey
Hi,
Please excuse me if this message was already delivered. I'm sending
it again as I suspect something went wrong with my original post
because it didn't get cross-posted to comp.lang.ruby and there were
no replies from a typically very helpful audience.
Pete
Original message:
I'm liberally helping myself to some of the ActiveRecord code. In
this code there are a handful of class methods that dynamically
create singleton methods to override the base methods. A simplified
version follows:
class SingletonBase
class << self
def table_name
reset_table_name
end
def reset_table_name
puts "reset_table_name called"
name = self.name
sing = class << self; self; end
sing.class_eval "def table_name; #{name.inspect}; end"
name
end
end
end
(I hope that simplifying the code didn't remove anything of importance.)
In this code the first time SingletonBase#table_name is called it
calls SingletonBase#reset_table_name. reset_table_name in turn
creates a singleton class and adds a method that overrides table_name
to return what was just calculated.
Fine.
But my question is, is there any reason to prefer this method over
using class instance variables, which seem a little clearer and
simpler? Ala:
class InstanceBase
class << self
def table_name
@table_name || reset_table_name
end
def reset_table_name
puts "reset_table_name called"
@table_name = self.name
end
end
end
If both of these classes are exercised as follows, the results are
comparable:
class Sub_SingletonBase1 < SingletonBase
p table_name
p table_name
end
class Sub_SingletonBase2 < SingletonBase
p table_name
p table_name
end
class Sub_InstanceBase1 < InstanceBase
p table_name
p table_name
end
class Sub_InstanceBase2 < InstanceBase
p table_name
p table_name
end
Output:
reset_table_name called
"Sub_SingletonBase1"
"Sub_SingletonBase1"
reset_table_name called
"Sub_SingletonBase2"
"Sub_SingletonBase2"
reset_table_name called
"Sub_InstanceBase1"
"Sub_InstanceBase1"
reset_table_name called
"Sub_InstanceBase2"
"Sub_InstanceBase2"
Note that there are class methods in ActiveRecord that _do_ use class
instance variables, but not all. In particular for setting/getting
table_name, primary_key, inheritance_column, and sequence_name,
basically everything that can be set by the user. So, what benefit
is derived from using virtual/meta/singleton/eigen-classes over class
instance variables?
Regards,
Pete
Please excuse me if this message was already delivered. I'm sending
it again as I suspect something went wrong with my original post
because it didn't get cross-posted to comp.lang.ruby and there were
no replies from a typically very helpful audience.
Pete
Original message:
I'm liberally helping myself to some of the ActiveRecord code. In
this code there are a handful of class methods that dynamically
create singleton methods to override the base methods. A simplified
version follows:
class SingletonBase
class << self
def table_name
reset_table_name
end
def reset_table_name
puts "reset_table_name called"
name = self.name
sing = class << self; self; end
sing.class_eval "def table_name; #{name.inspect}; end"
name
end
end
end
(I hope that simplifying the code didn't remove anything of importance.)
In this code the first time SingletonBase#table_name is called it
calls SingletonBase#reset_table_name. reset_table_name in turn
creates a singleton class and adds a method that overrides table_name
to return what was just calculated.
Fine.
But my question is, is there any reason to prefer this method over
using class instance variables, which seem a little clearer and
simpler? Ala:
class InstanceBase
class << self
def table_name
@table_name || reset_table_name
end
def reset_table_name
puts "reset_table_name called"
@table_name = self.name
end
end
end
If both of these classes are exercised as follows, the results are
comparable:
class Sub_SingletonBase1 < SingletonBase
p table_name
p table_name
end
class Sub_SingletonBase2 < SingletonBase
p table_name
p table_name
end
class Sub_InstanceBase1 < InstanceBase
p table_name
p table_name
end
class Sub_InstanceBase2 < InstanceBase
p table_name
p table_name
end
Output:
reset_table_name called
"Sub_SingletonBase1"
"Sub_SingletonBase1"
reset_table_name called
"Sub_SingletonBase2"
"Sub_SingletonBase2"
reset_table_name called
"Sub_InstanceBase1"
"Sub_InstanceBase1"
reset_table_name called
"Sub_InstanceBase2"
"Sub_InstanceBase2"
Note that there are class methods in ActiveRecord that _do_ use class
instance variables, but not all. In particular for setting/getting
table_name, primary_key, inheritance_column, and sequence_name,
basically everything that can be set by the user. So, what benefit
is derived from using virtual/meta/singleton/eigen-classes over class
instance variables?
Regards,
Pete