Archive for January, 2011
attr_accessor with default in Ruby
If you aren’t in rails (hello to both of you) the lack of an attr_accessor with a default value is very annoying. I wrote up the following:
module ExtendAccessors def attr_accessor_with_default name, *default, &block if(default.size >= 1) define_method name.to_sym do instance_variable_set("@#{name}", default[0]) unless instance_variable_defined?("@#{name}") instance_variable_get("@#{name}") end elsif block_given? define_method name.to_sym do instance_variable_set("@#{name}", instance_eval(&block)) unless instance_variable_defined?("@#{name}") instance_variable_get("@#{name}") end else raise "Must either provide a default value or a default code block" end define_method "#{name}=".to_sym do |value| instance_variable_set("@#{name}",value) end end end
which supports the following syntax:
class A extend ExtendAccessors attr_accessor_with_default :some_map, {} attr_accessor_with_default :some_object do AnotherObject.new(self) end end
Meaning of ’self’ in Ruby
This came up today. When defining classes in Ruby “self” can refer to the class or the instance of that class depending on the context and understanding which is which is important.
When defining a class “self” in the context of the class definition refers to the object representing the class being defined. When in a (non-class-level) method “self” refers to the instance of the object. So:
class SomeClass #dynamically add a method to the SomeClass object. #self is the SomeClass class object #now I can call SomeClass.class_level_method def self.class_level_method self == SomeClass #this is true.... end #define an instance level method def instance_level_method self #this is now an instance of the object end end
This syntax may make more sense in terms of the following
class SomeClass end #this can be done outside of the class definition def SomeClass.class_level_method echo "hi" end c = SomeClass.new d = SomeClass.new #class objects are notspecial in this regard. #You can do the same thing to #a specific object instance of any other type. def c.specific_instance_method #this method is defined just for this #specific instance of this class end c.specific_instance_method #no problem d.specific_instance_method #nope!