Peter's Blog

Redefining the Impossible

Rubyisms


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
Toggle Line Numbers

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
Toggle Line Numbers

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
Toggle Line Numbers

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.


Filed under: ruby

Sorry but comments on this post are now closed.