Explicitly setting iVar class in Ruby (ala Obj-C) -


i'm experienced obj-c/java programmer, , getting ruby. fact it's dynamic great (re-opening classes awesome!) there's 1 thing bugs me/worries me when start writing ruby code.

i'd interested know ruby-ers (if anything) explicitly set type of ivars in own classes. can see, can set ivar object , ruby won't complain. if expect specific ivar of type, can cause problems down line. example:

class mystring   def initialize(mystring)     @mystring = mystring   end    def uppercase_my_string     @mystring.upcase   end end  st1 = mystring.new("a string!") st1.uppercase_my_string  st2 = mystring.new(["a string"]) st2.uppercase_my_string 

this code throw nomethoderror, since of course array has no method upcase. unfortunately doesn't tell went wrong (the line above, when creating str2) we're not helped when debugging (if str2 happens created several modules away in inconspicuous place) 1 natural step might add checks initialize follows:

class mystring   def initialize(mystring)     raise typeerror, "mystring ivar not string!" unless mystring.class == string     @mystring = mystring   end end ...same code before 

great, if accidentally create new mystring we're told how silly (and more importantly we're told when , not when fail. bit of pain type it's ok. next problem when decide use attr_accessors on ivar.

class mystring   attr_accessor :my_string   def initialize(my_string)     raise typeerror, "mystring ivar not string!" unless my_string.class == string     @my_string = my_string   end    def uppercase_my_string     @my_string.upcase   end end  st1 = mystring.new("a string!") st1.uppercase_my_string  st2 = mystring.new("good, it's string") st2.my_string = ["an array!"] st2.uppercase_my_string 

using setter defined, can sneaky , round error checking in initialize. once again has problem of throwing exception in uppercase_my_string , not when accidentally set @my_string array.

finally, create accessors manually , add error checking massive pain... there quicker , easier way this. or being closed minded , not dynamic enough?

thanks!


aside: know in obj-c still have same problem @ runtime, typically you'll spot compiler error saying you're assigning object of type array variable of type string (or similar), @ least we're warned happens

in practice these sorts of type problems pretty rare. if want paranoid (since they you), can send input through to_s ensure have string:

def initialize(my_string)   @my_string = my_string.to_s end 

then can mystring.new(6) , work expected. of course, can mystring.new([6, 11]) , nonsense.

if want my_string string wouldn't explicitly check class. cause problems if has subclassed string you'd want @ least use is_a?:

def initialize(mystring)   raise typeerror, ... unless mystring.is_a? string   @mystring = mystring end 

there's to_str method check:

def initialize(mystring)   raise typeerror, ... unless mystring.respond_to? :to_str   @mystring = mystring.to_str end 

implementing method (in circles) indicate thing string-like enough string. think calling to_s better idea though, make things behave more people expect in ruby.

as far mutator problem concerned:

st2.my_string = ["an array!"] 

you don't have let write want properties: classes aren't structs. automatically define accessor , write own mutator automatically slip in to_s call:

class mystring   attr_reader :my_string   def initialize(my_string)     self.my_string = my_string   end    def my_string=(s)     @my_string = s.to_s   end    def uppercase_my_string     @my_string.upcase   end end 

basically, don't worry types in ruby, worry methods responds to. and, if want string, make string calling universal to_s method (which string interpolation, "#{x}", do).


Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -