Too Cool for Internet Explorer

Sunday, January 27, 2008

Ruby and IRB

IRB is a Ruby tool that I’m not a fan. When a Ruby newbie uses it, there are some kind of behavior that most confuses then clarify.

But there are a lot of users, so I need to understand and explain how it works.

IRB, created by Keiju Ishitsuka, stands for Interactive Ruby Shell, and acts like expected, you send it a Ruby statement, that statement is executed and IRB return the last evaluated expression and some other tips.

But How ?

By nature, if used without arguments the Ruby interpreter wait for additional information.

D:\>ruby  

3.times do

puts 'step'

end

^D

step

step

step

D:\>

The Ruby interpreter, has two useful switches to achieve that:

  • -e let you specify a script on the command line to be executed.
  • -n wraps the specified script in a "while gets()" loop.

So, Keiju has used these to implement this tool. Try it yourself with the following command:

ruby -n -e 'puts eval($_)'

And IRB gives some useful tips on the command prompt. Just after started, IRB will show a command prompt like this:

irb(main):001:0>

This prompt has three parts delimited by “:” “irb(main)” are the actual program and session names, “001” is the actual line number and the final “0” is the indent level or in other words, the number of open blocks you currently have.

Indent level sample:

D:\>irb

irb(main):001:0> level = 0

=> 0

irb(main):002:0> if level == 0

irb(main):003:1> level = 1

irb(main):004:1> if level == 1

irb(main):005:2> level = 2

irb(main):006:2> end

irb(main):007:1> end

=> 2

irb(main):008:0> exit

D:\>

Program level and session name sample:

D:\>irb

irb(main):001:0> class Number

irb(main):002:1> def choice

irb(main):003:2> 'even'

irb(main):004:2> end

irb(main):005:1> end

=> nil

irb(main):006:0> mynumber = Number.new

=> #

irb(main):007:0> puts mynumber.choice

even

=> nil

irb(main):008:0> irb Number

irb#1(Number):001:0> def choice

irb#1(Number):002:1> 'odd'

irb#1(Number):003:1> end

=> nil

irb#1(Number):004:0> irb_exit

=> # irb::irb: context="# IRB::Context:0x2e46b58" , @signal_status=:IN_EVAL, @scanner=# rubylex:0x2e467fc

irb(main):009:0> puts mynumber.choice

odd

=> nil

irb(main):010:0> exit

D:\>

Monday, January 21, 2008

Ruby and strings


Strings are just one of the data types supported by Ruby. Like other UNIX world script languages, strings in Ruby could be delimited by double-quotes (“…”) or single-quotes (‘…’), with different meanings.

Double-quotes, are used when we need complex evaluations

(interpolation), on string contents, or scape codes substitution, like \t to tab and \n to new line, and any one expression delimited by #{}.

The same is not possible when single-quotes are used, which only admits some basic substitutions, like \’ and \\, that allow the use of the ‘ and \ characters on string.

Another option to delimit strings is using %q/string/, meaning the same as single-quotes, but no substitution at all, and %Q/string/, meaning the same as double-quotes.

The “/” delimiter could be replaced by any non alpha-numeric character with the same behavior, like: %q(string), or %Q@string@. This flexibility, let you keep a clean code, according with the characters composing your string.

Strings could be defined, across more then one line, with no problem.

Strings are objects (instances), from String class.


# p002e.rb
msg = 'attention! '
puts "msg: #{msg + msg}"
"#{ 3.times do ; puts 'bye!' end }"
puts %Q|This way equals to " \nbut we can have ' too.|
puts %q[And this one equals to \' and don't replace a\ny\thing]
puts %Q@Now with some subs\ti\tutio\ns@
puts '==============='
puts "#{msg * 3}"
puts 'Here \t we have, sandwiches \n from Tob\'s \\ McCarty\'s'
longo = 'One string, could
start on one line and
end on another'
puts longo
puts "Here \t we have, sandwiches\nfrom Flash \\ Zebra\'s"
puts 'Now we have a "special" word'
puts 'Who am I ?'.class
puts '==============='
puts 'What I can do ?'.methods
puts '==============='

Saturday, January 12, 2008

Ruby 1.9.0 < Windows > 1.8.6


I have to do something about the recent release of Ruby 1.9.0.

And decided to test all samples and exercises I have done when engaged as a student on RubyLearning.com Free Ruby Course.

I use Windows, and would like to go to 1.9.0 and back to 1.8.6 easily.

There is no difficult to accomplish that with the binaries.

I had Ruby 1.8.6 installed (on E:\Ruby) with the "one click installer" tool, everything working including some gems.

Here is my step by step procedure:

  • I down loaded the Ruby 1.9.0 windows binary file (ruby-1.9.0-0-i386-mswin32.zip), near 11,5 Mb, from Ruby-Lang.org.
  • After that, I have created a folder like E:\Ruby-1.9.0, put the zip file there and unzip it.
  • Then, renamed E:\Ruby to E:\Ruby-1.8.6 and E:\Ruby-1.9.0 to E:\Ruby.
  • That is it. Now I'm using Ruby 1.9.0

This download binary doesn't have any add-on tool and I miss SciTE from the beginning.

Once more, pretty easy: just copied the SciTE sub-folder under E:\Ruby-1.8.6, to E:\Ruby, and now I get Ruby 1.9.0 and SciTE, just like the old one.

I think gems will work the same, will have to test.

To get back to 1.8.6 ?

No difficult at all: just renamed E:\Ruby to E:\Ruby-1.9.0, and E:\Ruby-1.8.6 to E:\Ruby

I have found a detailed change log list on Ruby 1.9.0 at Eigenclass.org

Saturday, January 5, 2008

Ruby and Active Record vs SQL


There was something bugging me these last days...

I have seen all kind of facilities: act like this, act like that, and a lot of “Rails makes it for you” all around. But, when your application grows, or much more common, you have to deal with legacy applications and data models, things don’t work so easy.

Two weeks ago when I was testing some Ruby / Active Record code accessing oracle tables on my legacy enterprise model. Everything was fine when I was testing some simple table access.
Then, I remember my current java work. Dealing with much more complex tables and queries. In fact, queries are the starting point on my java applications. We have tables with more then 50 columns, an unnormalized table to avoid several joins, three unions on a single query to catch “old database model” data, things like that!

And on an “enterprise” environment, there are rules to be followed.
For example:

  • Never EVER use “select *”.
  • Every single query MUST be “explained” and DBA approved BEFORE going into production state.


So, Wonderland far way, I start researching some practical alternatives, and find these:

Lesson learned: automation is fine, abstraction is a must, but real world is Rock solid, don't try to kick it out.

Some times will be necessary to SQL your code.