Some rubyisms to learn:
Convert String to Array of Characters
irb(main):004:0> "123".split(//) => ["1", "2", "3"]
Determine if an Object has a certain method
irb(main):006:0> "123".respond_to?( :split) => true
This is useful for working in terms of what objects can do rather than what objects are.
1 def ReadFile( fd) 2 # 3 # If fd does not work with readlines (File or StringIO) then 4 # assume it is the name of a file to open 5 # 6 if not fd.respond_to?( :readlines) 7 fd = File.open( fd) 8 end 9 10 fd.readlines.each do |strLine| 11 print strLine 12 end 13 end
If a File object or StringIO object or anything else with a 'readlines' method that returns a collection of strings is passed to a function then it will process those lines. If the thing passed has no such method it is assumed to be a file name and the file is opened and the strings read from it.
Read Strings from Memory rather than a File
If you are sending test data to a function it is easier to create a StringIO object to pass the test strings into the function than writing the strings to a temporary file and asking the function to read the file:
strLines = << EOF these are some test strings they are declared in the source without having to write to a temporary file EOF o = StringIO( strLines) ReadFile( o)
Destructors?
I read that ruby has no destructors. If you want to control a resource and make sure it gets freed you can use the following paradigm:
1 2 class MyThing 3 def Run 4 begin 5 # 6 # Allocate a thing 7 # 8 o = AllocateAThing() 9 # 10 # Pass it to the block that is passed to this function 11 # 12 yield o 13 ensure 14 # 15 # Whatever happens, errors, returns, make sure the 16 # thing is freed. 17 # 18 FreeThing( o) 19 end 20 end 21 end 22 23 # 24 # Create thing wrapper 25 # 26 m = MyThing.new 27 28 # 29 # Run thing and pass block 30 # 31 m.Run do |oThing| 32 # 33 # The block is called with a reference to the thing 34 # 35 oThing.DoStuff() 36 end
It's an interesting way of doing things but it gets messy if you want a number of Things:
1 # 2 # Create thing wrapper 3 # 4 m = MyThing.new 5 6 # 7 # Run thing and pass block 8 # 9 m1.Run do |oThing1| 10 m2 = MyThing.new 11 m2.Run do |oThing2| 12 oThing1.DoStuff() 13 oThing2.DoStuff() 14 end 15 end
Exceptions
I'm hooked on the RuntimeError exception:
irb(main):012:0> begin irb(main):013:1* raise RuntimeError, "Ouch that hurt" irb(main):014:1> rescue RuntimeError => err irb(main):015:1> print "Sh!t Happens:\n" irb(main):016:1> print err irb(main):017:1> end Sh!t Happens Ouch that hurt=> nil
RuntimeError is suitably catchall, everything happens at runtime. You pass it a string that explains the problem and can display/log/ignore it in the exception handler.
Argh
To extract a letter from a string:
irb(main):033:0> "123"[0,1] => "1"
The more intuitive way gives you the code of the letter instead:
irb(main):034:0> "123"[0] => 49
This is what you would expect in C but not from a modern scripting language.
Twitterings
