Too Cool for Internet Explorer
Showing posts with label Ruby Language. Show all posts
Showing posts with label Ruby Language. Show all posts

Tuesday, June 15, 2010

Peek-a-Boo (Pik a Ruby)


I have seen so many people around talking about testing different Ruby versions in Linux and OS/X.

What about using different Ruby versions in Windows?

I have been doing the job manually since the beginning, but there is a cool alternative.


It is a Multi-Ruby Manager for Windows.

A clever solution and there is extremely simple to get it working.

Let’s see:

Saturday, April 10, 2010

Who cares about a nanosecond?

Things are going faster and faster, so, why still measuring times in a second precision?

Could you think about how many files are uploaded from users in a specific city within a second?

Let’s say, any country capital with a high speed broadband service.

Try to put them all in order. Which arrives first?

Most of the current relational databases support Timestamp data:

Oracle ........ '2007-08-08 09:00:00.123456789'
DB2 ........... '2002-10-20-12.00.00.123456'
PostgreSQL .... '2003-07-29 13:19:30.532'
MySQL ......... '1970-01-01 00:00:00'

But most of it doesn’t consider nanoseconds properly.

People tend to consider that only Real Time Systems have better precision of time measurement needs, but that is not true.

I have recently developed a business application where users can upload files.

Files are uploaded in groups (fifteen maximum). It was important to know the order on which files have been upload.

Depending on the size of the files and users’ internet broadband capacity, some files could be uploaded in the same second.

So, that is the reason to store the uploaded date in the table as a Timestamp column.

The problem starts when trying to feed the required data using the language resources only. I know we can provide current timestamp from the database itself, but if you are not using a relational database and needs to store the timestamp?

Java and Python for instance, have nanoseconds support, but deal with them separately from the date and time. And about Ruby?

The Good new is that Ruby 1.9 does the job nice this way:

Time.now.strftime('%Y-%m-%d-%H:%M:%S.%6N')

Where you can specify the desired precision in %3N, %6N or %9N, but will need a superfast machine to test them all.

Here is a working sample:



Another consideration you must take into account: the O.S. used:

  • Solaris and Linux already support nanosecond precision.
  • The situation on Mac OSX is not that good, since only microseconds are available.
  • Windows, on the other hand, supports nanoseconds, but have a 10ms granularity limit.

So, depending on O.S. running your code, you may need some extras to get the timestamp in the complete form.

The Bad new is that Ruby 1.8 doesn’t support nanoseconds.

Back to the real World, we must admit that most of people out there are using Ruby 1.8.6 under Windows.

So, I have made a working snippet for Ruby 1.8.6 on Windows that could at least, provide data to the PostgreSQL centisecond format.

Saturday, March 13, 2010

Ruby TransParenTheses

First thing first, the definition:

Parentheses (singular, Parenthesis)—sometimes called Round Brackets, Curved Brackets, Oval Brackets, or just Brackets, or, colloquially, Parens.

Contain material that could be omitted without destroying or altering the meaning of a sentence.

I think the above definition, must be considered when discussing about the non mandatory Parentheses use in Ruby.

On many discussion groups, people are questioning Matz’s option to not make the use of parentheses mandatory in Ruby Language, mostly around Ruby methods parameters.

Apparently this decision is becoming stronger.

If you run the following piece of code in Ruby 1.8.6, you will get a warning:

p Array.new 3, 1

ptest01.rb:1: warning: parenthesize argument(s) for future version

The same occurs with this one:

p Array.new (3+1), 1

ptest02.rb:1: warning: don't put space before argument parentheses

But if you run them in Ruby 1.9.1 they will pass with no warnings.

Do you really think it would be better this way?

p(Array.new((3+1), 1))

When developing an application I like to put myself in the user’s shoes.

As a user of a reading text (program), I would like to read it easily.

Some times the absence of a rule is not that good.

But the strict use of a rule could be bad as well.

I have this little example:


I can say Matz is right to keep parentheses optional in Ruby, leaving to users the final decision on its usage.

Saturday, February 13, 2010

Ruby Symbols Ultimate Guide

In Ruby, a Symbol is a special class used to define a constant named label.

A symbol is defined using a colon ":" in the beginning.

Example:
:my_test_symbol

A symbol is not a string, but it has a string representation and an object identifier.

Ruby newbies ask about advantages on using constants over variables, or symbols over both, very often.

First of all, you must know there are no really Constants in Ruby. They are just a convention on variable names (starting with uppercase letters).

You can in fact, change the "constant" values along your ruby program.

That way, it is your responsibility to keep your Ruby "constants" with the same value almost all the time.



Strings, even with the same content are different objects, so, are identified differently.



So, strictly technically speaking, Symbols are pointers to memory objects containing the symbol name.

Differently from Ruby variables or even Ruby "constants", Symbol values could not be changed.



In fact you couldn’t even access the Symbol content unless through a Symbol#to_s method.



Remarkable points here are:
  • When Symbols are better then Strings?
  • Which are the advantages and drawbacks from one over the other?

If you have a few unique string values, and will use them the way they are (no concatenation, upper or lower case, no nothing), Symbols are the right tool for the job.

In any other circumstance, stick with strings. They are not that much slower then Symbols, and much more flexible.

Symbol scope is a bit different and need to be considered.



About performance, you need to have a few points in mind when dealing with a great amount of strings and Symbols:

About memory:

Strings are Garbage collected, Symbols are not.

So, Symbols will be there while your program is running, which can be a great memory consumer.

Have you ever considered how many objects you will have when you set a variable inside a loop?



When creating a great amount of Strings and Symbol, how did the operation compares in performance?



About CPU Time:

When you make Strings comparison rather then Symbols comparison, it could be a great CPU time consumer, since the comparison must be done for each character in the string.



Symbol "values" can be retrieved in many different ways:



Usage:

Symbols should be used whenever referring to a name (identifier or keyword), even if that name doesn’t exist in actual code yet.

  • Naming keyword options in a method argument list
  • Naming enumerated values.
  • Naming options in an option hash table.



That is it about Ruby Symbols

Tuesday, August 5, 2008

Bitwising Ruby


This week some students come up with solutions using or appropriate to use bitwise operations, so, it is time to refresh the memory about that subject.

Binary numbers are just a bunch of Zeroes and Ones.

Representing: true / false; on / off, the base of the computer science.

Some Powers of Two:


power of 2 base-10 base-2 (binary)
20 1 1
21 2 10
22 4 100
23 8 1000
...
29 512 1000000000
210 1024 10000000000
211 2048 100000000000
212 4096 1000000000000
...

Binary numbers:

23 = 16 + 0 + 4 + 2 + 1
1 0 1 1 1 = 10111

252 = 128 + 64 + 32 + 16 + 8 + 4 + 0 + 0
1 1 1 1 1 1 0 0 = 11111100


Binary numbers in Ruby:

bin_num1 = 0b10111
bin_num1 = 0b11111100


The bitwise operations in Ruby:

bin1 = 0b100011010101
bin2 = 0b101010000010
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts ' = the bitwise or operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ |'
bin_result = bin1 | bin2
puts sprintf("%12b", bin_result)

puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts ' = the bitwise and operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ &'
bin_result = bin1 & bin2
puts sprintf("%12b", bin_result)

puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise exclusive or operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ ^'
bin_result = bin1 ^ bin2
puts sprintf("%12b", bin_result)

puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise negation operation ='
puts '100011010101 <- bin1'
puts '------------------ ~'
bin_result = ~bin1
puts sprintf("%12b", bin_result)
puts '^'
puts '|'
puts '+----- Ruby would like to print 1s forever here'

puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise left shift operation ='
puts '101010000010 <- bin2'
puts '------------------ <<'
bin_result = bin2 << 3
puts sprintf("%12b", bin_result)

puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise right shift operation ='
puts '101010000010 <- bin2'
puts '------------------ >>'
bin_result = bin2 >> 5
puts sprintf("%12b", bin_result)


Parity Check:

It is the easiest way to check if a number is odd or even.

Check the least-significant bit (one's place) in the binary representation:
If it is 0 then the number is even
If it is 1 then the number is odd

def odd_even(number)
puts "#{number.to_s} is #{number & 1 == 1 ? 'odd' : 'even'}"
end

odd_even(8)
odd_even(-3)
odd_even(104)
odd_even(127)
odd_even(32)
odd_even(51)


“Powerful” Bit Operations:

Observe:

11 00001011

22 00010110

44 00101100

If we “shift” the bits one place to the left, and add a 0 at the last place, we double the number.

A final example:

We want to know if a string has just words and spaces, no numbers or special characters:

class String
def are_just_words?
is_false = 0b0
self.split('').collect { |character|
is_false = is_false | ((' '.eql? character or
(65..90).include? eval("?#{character}") or
(97..122).include? eval("?#{character}") or
(192..255).include? eval("?#{character}"))? 0b0 : 0b1)
}
is_false == 0b0 ? true : false
end
end

puts 'Atenção eloqüente ortográfico filosófico'.are_just_words?

Returns true

Now try to include numbers and / or special characters and see what happens.

Sunday, March 16, 2008

Ruby from Test::Unit to RSpec part 3 of 3 b

The second part of this article, is about the Spec framework, the one that give Rspec the original name.

After the customer and the developer agree, over a Story describing the business behavior, is time to go on with a more techical specification.

The Spec framework provides RSpec a Domain Specific Language with which you can express executable examples of the expected behaviour of a system.

Thinking about the grading process, we need to describe our process behaviour, so the initial structure will be like this:


require 'spec'
require 'grading'

describe Grading do
...
end

Now, to describe the behaviour, use the folowing sample structure:

1 - To stablish states, of the involved objects.

before(:each) do
(1..9).each { |i| @stack.push i }
@last_item_added = 9
end

2 - RSpec adds "should" and "should_not" methods to any application object.

@student.grade.should ...
post.should_not ...

3 - And a "expectations" set.

be_...(...)
have(...).(...)
raise_error(...)

All together now…

# grading_spec.rb
require 'spec'
require 'grading'

describe Grading do
GradingOverflowError = '123'
before(:each) do
@grading = Grading.new
end

it "should score more then 50 to pass" do
@grading.score(51) == 51
@grading.status('pass').should == 'pass'
end

it "should complain when score more then 100" do
lambda { @grading.score(101) }.should raise_error(GradingOverflowError)
end
end

# grading.rb
class Grading
def score(grade)
if grade > 100
raise '123'
end
end

def status(status)
@status = status
end
end

To run this specification, use this command:

ruby grading_spec.rb --format specdoc

And should get the following result

Grading
- should score more then 50 to pass
- should complain when score more then 100

Finished in 1.219 seconds

2 examples, 0 failures

Now try to add this specification:

it "should get status 'pass' to be assigned to next batch" do
@grading.status('pass') == 'pass'
@grading.assign_batch('pass').should == 3
end

And try to get this result:

Grading
- should score more then 50 to pass
- should complain when score more then 100
- should get status 'pass' to be assigned to next batch

Finished in 0.875 seconds

3 examples, 0 failures

Now start RSpec in practice on the next project.

Sunday, March 2, 2008

Ruby from Test::Unit to RSpec part 3 of 3 a

This would be the last article on this series, but I decided to split this last article about RSpec in two parts:

  • The Story framework (this one)
  • The Spec framework (the next one)

The reason to do that is the importance of this part over the next one. It is near impossible to find useful and complete samples on the Story framework nowadays.

This is the most important part on RSpec, the one that let the customer and the developer to use the same language on understanding the business behavior and specifying the application implementation.

Behaviour Driven Development or BDD, is a thinking evolution on TDD, basically changing from a developer view point to a problem solver view point. Changing from thinking about technical implementation details, to thinking about the problem itself, and how to provide value to the customer through software.

Even with TDD, developers are, most of the time, thinking about technical aspects of the system and often write poor tests.

BDD helps to evolve into a deeper analisys of what the problem really is, which context does the problem apply to, and what are the specifications proof to show that a solution can be demonstrated, forcing developers to focus on the problem and gain a full understanding on it prior to coding.

As system or business analysts, we all agree that would be nice to express customer desires and application specifications, on a common business domain language and vocabulary.

To achieve that RSpec merge Dan North's RBehave into it, since version 1.1, turning RSpec into a BDD, two pieces framework for Ruby, used to write and execute examples of how the application should behave:

  • A Story framework describing application level behavior.
  • A Spec framework describing object level behavior.

Starting with the Story framework, the story narrative should contain a Role, a Feature and a Benefit. To ensure that we use a template like this:

As a (Role)
I want (Feature)
So that (Benefit)

For example:

As a customer
I want to withdraw cash from an ATM,
so that I don't have to wait in line at the bank.

From this starting point and with the agile TDD in mind, we need to specify the acceptance criteria in terms of scenarios. Again, to ensure that we use a template like this:

Given (some initial context, the givens)
When (an event occurs)
Then (ensure some outcomes)

For example:

Scenario 1: Account is in credit
Given the account is in credit
And the card is valid
And the dispenser contains cash
When the customer requests cash
Then ensure the account is debited
And ensure cash is dispensed
And ensure the card is returned

Now for a practical example, imagine a conversation between a developer and a customer:

Developer: describe how to evaluate a student performance.
Customer: Given a specific student, if the student achieves a grade of 50 it should be assigned to a second chance on the summer class. If the student grade is greater than 50, the student pass, if the grade is less then 50, the student fails.

This is a story about a student's grade evaluation.
The text up here above the Story: declaration won't be processed
So you can write whatever you wish, like this kind of comments!

Story: Student grade evaluation

As a school staff member
I want to know if with a specific grade a student has stay, pass or fail
So that I can easily assign (him|her) a new status

Scenario: student grade is just the average
Given a student named 'Monique'
When the student is given a grade of 50
Then the student batch should be same

Scenario: student grade is sufficient to pass
Given a student named 'Michelle'
When the student is given a grade of 60
Then the student batch should be next

Scenario: student grade is insufficient to pass
Given a student named 'Mike'
When the student is given a grade of 40
Then the student batch should be same

Each Given, When and Then is a Step. The Ands (if any), are each the same kind as the previous Step.

Now with the grade.txt file above we need to check it with RSpec.

To do that we just need a simple Ruby program like this.

#!/usr/bin/env ruby
# grade.rb
require 'spec/story'

with_steps_for :grade do
run 'grade.txt'
end

Runing this program, the story with 3 scenarios will be analized, and produce an output with a final conclusion like this:

3 scenarios: 0 succeeded, 0 failed, 3 pending

And nine pending steps alerts, three on each scenario

The scenarios fragments, the Givens, events, and outcomes, are enough to be represented by executable code.

Steps are defined in Ruby like this:

#!/usr/bin/env ruby
# grade_steps.rb
steps_for(:grade) do
Given("a student named '$name'") do |name|
@student = Student.new(name)
end
When("the student is given a grade of $grade") do |grade|
@status = @student.evaluate(grade)
end
Then("the student batch should be $batch") do |status|
@batch = @student.assign_batch(status)
end
end

And objects involved are supported by a class defined on a program like this:

#!/usr/bin/env ruby
# student.rb
class Student
def initialize(name)
end
def evaluate(grade)
end
def assign_batch(status)
end
end

Now we need to include these programs on the check program above, and it will look like this:

#!/usr/bin/env ruby
# grade.rb
require 'spec/story'
require 'grade_steps'
require 'student'

with_steps_for :grade do
run 'grade.txt'
end

Monday, February 18, 2008

Ruby from Test::Unit to RSpec part 2 of 3

Now that we know about unit tests, we can go a step further. TDD (test driven development). But what is that on the first place ? Different from Unit tests, in TDD, tests always comes first.

The best definition on TDD basic idea comes from Manfred Lange, one of the csUnit Lead Developers:

"Test a little, code a little, refactor a little -- in that sequence! And the rhythm here is not in hours or days. The rhythm for the entire sequence is seconds or minutes. Run tests frequently, preferably as often as possible. With TDD the test always comes first, while with 'unit testing' in the broadest sense this is not clear. Generating tests after-the-fact is not considered to be TDD. Sometimes I even prefer the term 'Test-Driven Design' as it makes clearer what this really is about."

When we talk about TDD, we are not talking just about tests. We are talking about a development process, consisting on:

  1. Create a test code
  2. See the test fail
  3. Create the code to make the test pass.
  4. Refactoring the code
  5. Refactoring the test
  6. Do it again

The principal benefit on TDD design is that it will make OO design goals easy to achieve: TDD is a technique for determining class structure by making testability a first class consideration in your design. Focusing on testing a unit of code at a time leads to creating cohesive classes with a distinct purpose and responsibility. The need and desire to quickly setup an isolated unit test on a class will lead to a loosely coupled design.

The use of UML and CRC, is based on the belief that it is easy to design ideas on abstract artifacts, because code is difficult to change once written. This assumption could be changed because TDD resulting code is cohesive and loosely coupled. With a couple of good tools automating the tests and assembling the code, can make this technique much more efficient.

There is an interesting (but incomplete) series of articles on Jeremy D Miller's blog about a set of “TDD laws”.

Coming from Kent Beck's “Test-Driven Development By Example” book, and adapted to Ruby by Rafael C. Schouery, here is a sample on how to create a Fibonacci number function recursively using TDD.

First, we would like that fib(0) = 0. So, we start to write down our test.

require 'test/unit'

class TestFibonacci <>

To get the test pass, we need a Fibonacci class and a self.fib method on it.

class Fibonacci
def self.fib(n)
return 0;
end
end

With the tests going on, we could tests if fib(1) = 1, so we change the test_fib method to include this condition.

def test_fib
assert_equal(0,Fibonacci.fib(0));
assert_equal(1,Fibonacci.fib(1));
end

Which obviously will not pass. We can change the self.fib to the following.

def self.fib(n)
return 0 if(n == 0)
return 1
end

Now the tests are passing, but there is a code repetition, a bad practice. Refactoring the code with the DRY principle, we have:

def test_fib0
cases = [[0,0],[1,1]]
cases.each do |c|
assert_equal(c[1],Fibonacci.fib(c[0]))
end
end

Now we have pair tests to try (n,fib(n)). We can add the pair (2,1) and the tests still pass. If we add the pair (3,2) the test will fail. we can fix the code to fix this problem.

def self.fib(n)
return 0 if(n == 0)
return 1 if(n <= 2) return 2 end

Now we have the tests passing, we can make a more generic code, and instead of 2 we can return:

fib(n-1) + fib(n-2)

And now we have the final code:

require 'test/unit'
class TestFibonacci < cases =" [[0,0],[1,1],[2,1],[3,2]]" n ="="">


That is it TDD.

Sunday, February 10, 2008

Ruby from Test::Unit to RSpec part 1 of 3

What is this all about ? Coding tests for applications ? Why ?

The technical view:

  • Avoid creating a bug when fixing another one.
  • Don't use to play with the program to find errors (it is slow).
  • Unit tests are the first step on TDD (test driven development).

The programmer view:
  • I will not write tests, that is what testers do.
  • Writing tests is a waste of time, it slows down my productivity.
  • My code works, I'm a good programmer, and I don't need to write tests to prove it.

The tester view:
  • Programmers couldn't write tests, that is what testers do.
  • If programmers write tests where our jobs will go ?
  • If you ask a programmer to write tests you know nothing about tests.
Unit tests before code, advantages:

Creating unit tests before the program solution, developers will consider what need to be done. Requirements become stronger when supported by tests. Couldn't be misunderstanding on a specification written in the form of executable code.

The feedback is immediate while the work goes on. Creating unit tests first, developers can feel when all necessary conditions and functionality have being considered and implemented.

There is also a benefit to system design. Creating tests first your software design will be influenced by a desire to test everything valuable to the customer, reflecting on an easier to test design.

How to create a Unit test ?

  • Require 'test/unit' in your test script.
  • Create a class that subclasses Test::Unit::TestCase.
  • Add a method that begins with "test" to your class.
  • Make assertions in your test method.
  • Optionally define #setup and/or #teardown to set up and/or tear down your common test fixture.
Comes from Google an example from the Ruby/Password library's unit tests.

require 'test/unit'
require 'password'

class TC_PasswordTest < Test::Unit::TestCase

def test_check
# Check for a weak password.
pw = Password.new( 'foo' )
assert_raises( Password::WeakPassword ) { pw.check }

# Check for a good password.
pw = Password.new( 'G@7flAxg' )
assert_nothing_raised { pw.check }

# Check for an exception on bad dictionary path.
assert_raises( Password::DictionaryError ) { pw.check( '/tmp/nodict' ) }
end

end

This is just a basic sample, but that is the idea for now.

You can search for available Ruby assertions on Ruby-Doc.

Test Case is a class that inherits from Test::Unit::TestCase, and contains a "testing strategy", comprised of contextually related tests, and each test is a method named test_something.

Test Suite is a collection of test cases. When a test suite is executed, each test belonging to it is executed. A suite is excellent for continuous-build integration for example. Tests could be aggregated on a suite when needed.

Test Fixture is a way to group "setup" and "teardown" methods, to prepare your test unit framework to prepare the environment to your tests.

Test Harness is a collection of software and test data configured to run unit tests under varying conditions monitoring its bahavior and outputs.

Assertions are the heart of unit testing, providing a way to define expected results for a test. The goal is to test the behavior, by setting the test to pass or fail according to an expected type and value.

Mock Objects mimics behavior of real objects on controlled environments, programmers can use these objects to meet the interface requirements on complex real functionalities, without calling complex underlying or collaborating classes.

Test Unit and command line options:

To see all options just call a test with the -h option.

ruby my_test.rb -h

The best options to try are:

-r which brings up a GUI interface.
-n and -t which specifies specific methods and classes to be tested

More on command line options in this Scott Patten's article.

Wednesday, February 6, 2008

Ruby duck typing effect


Last week we could see questions about to_s and to_str on the forum.

Some assumptions too:

  • Appears to be to_str an alias for to_s
  • Most classes implement to_s, just a few implement to_str.
  • There existences just confirm Ruby immaturity.
  • Some are automatic casting others are a "do it yourself" version.

So why are these to_str, to_int, to_ary methods there ?

There is a pragmatic example to help us with Roman numbers.

A Roman number is a representation of an integer, it is not a number it self, but has an integer behavior. So, for practical purposes, if we have a Roman number object, acting like an integer one.

To achieve that, Ruby has the "conversion protocols" concept, which means, an object may convert itself to an object of another class, and there are three ways to do that.

  1. Non strict methods like to_s and to_i. They may be applied on objects that are just near the desired behavior. On the Roman number example, we probably need the to_s method to get a string representation of a number.
  2. Strict methods like to_str and to_int. That are only used on objects that naturally have this kind of behavior. On the Roman number example, they are clearly representing integers, so, they should implement to_int.
  3. Numeric coercion, which let methods deal with different numeric parameters, based on the coerce method. It takes two numbers (a receiver, and a parameter), it returns a two-element array with representations of these numbers, but with parameter on the first element and receiver on the second. These two array elements are objects of the same class, so, therefore they can be added, subtracted, multiplied, compared, etc.

That is an evolving process, for example: the Pathname object responds different to to_str method on Ruby 1.8.6 and 1.9.0. It was considered a regular string behavior in the past, not any more.

A code to think:

require 'pathname'
path = Pathname.new("/tmp/myfile")
puts '================ strict methods'
name = path.to_s # not needed on 1.8.6
puts path.class
puts path.respond_to?(:to_str)
puts path.respond_to?(:to_s)
heading = "File name is " + name
puts heading
heading = "File name is " + path
puts heading # will not work on 1.9.0
puts '================ non strict methods'
def evaluate(parm_object)
if parm_object.respond_to?(:to_str)
puts parm_object + '2'
else
puts parm_object + 2
end
end
evaluate('2')
evaluate(2)
puts '================ numeric coersion'
puts (3.8).coerce(9).inspect
puts 8.coerce(3.5).inspect
puts (7.2).coerce(4.1).inspect
puts 4.coerce(7).inspect
puts '================ end of examples'

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.

Sunday, December 16, 2007

Rails, Rails and my Ruby weekend after

Rio on Rails is over, but was a great event.

Yeah, that was a good one. Well organized, all presentations on time, a participative audience. A great event, on all aspects.

Congratulations to everyone involved.


And Fabio Akita’s “The First Rails 2.0 Screen Cast” is making waves on the net.

Rio on Rails 2008. I want to be there !

Yesterday, another event “Rails for Kids”:

A charity Rails presentations marathon, we could follow at home with “TreinaTOM” web interface.

That was amazing!

I count 50-60 average audience following it along the day (almost from Brazil, but at least two from US).

And those presentations confirm my “Rio on Rails” feedback: I need to open my mind to some practices I don’t used to be familiar with.

Followed Google with just a few points:

  • Test Driven Development or Behavior Driven Development (the newest euphemism) with Ruby.
  • Domain Specific Languages and how to use .
  • Agile Development Techniques.

Thanks to: Danilo Sato, Ronaldo Ferraz and Vinicius M Teles / Marcos Tapajos, respectively to open my mind on that subjects.

Those last events are all about Rails, but I will not start with Rails yet.

So I have to find a way to practice the first two items with Ruby only.

About Unit Testing with Ruby, I started With Satish Talin.

By the way, on my research about TDD and DSL, I find a useful place to MetaProgramming, and keeping me DRY on “Ruby thinking way”.

OK, OK, I have to start with Rails ASAP...

That is Cool!

Sunday, December 9, 2007

My personal Ruby project

After working with java for a while, a problem came up to me.

Here at work we have an architecture checklist for all pre-production applications.

My recurrent problem is: lack of more descriptive comments on Javadoc for generated getters and setters on Database field’s value objects.

Unfortunately we access DB directly here no Hibernate, just some regular SQL on DAO, and associated VOs.

Here is an actual VO sample:

/**

* @return the cdNAT

*/

public java.math.BigDecimal getCdNAT() {

return cdNAT;

}

/**

* @return the cdSUCDESTPAG

*/

public java.math.BigDecimal getCdSUCDESTPAG() {

return cdSUCDESTPAG;

}

And here is a desired one:

/**

* @return the event’s nature from the payed indemnizations

*/

public java.math.BigDecimal getCdNAT() {

return cdNAT;

}

/**

* @return the office’s code from the payed indemnizations

*/

public java.math.BigDecimal getCdSUCDESTPAG() {

return cdSUCDESTPAG;

}

We have comments on all tables (and columns), on data base.

So my project is: create a Ruby application that will gather comments from database, join the terms: “return the” with the column comment and “from the” with the table comment, and create a really descriptive comment on Java source.

On the first version, will have to pass the java file and the table name.

On further versions, will try to do a deep analysis on corresponding DAO class, taking all table names, locating the child VOs and do the work there.

Current status:

  • I have all the SQL needed to the job tested using tiny Ruby programs;
  • I’m studying “active records” to use it on my Ruby programs;
  • Made some practical tests, and experiences to select a Ruby GUI, to get it done.

The future:

  • Extend this functionality to Ruby / Rails.
  • Try an open source project on that subject, or include this functionality on an open source project that already exists.
Any Help, suggestion, tip or reference Welcome

Friday, November 30, 2007

Ruby, modulus operator and POLS


Since I started my Ruby learning process, one of the most basic and important things I consider, is the POLS (Principle of the Least Surprise).

This week, a new question about “string pattern formatting”, came up on the forum.

Considering this code:

'%0.2f' % ((f.to_f - 32) / 9 * 5)

Which is the meaning of the second “%” ?

After some research, I found two options on that “formatting” subject.

  1. You can format your data immediately, using the printf method.

f = -123.12345

puts sprintf('%0.3f', f)

  1. You can create a template, and interpolate data with it later.

template = '%s, has always been in %s with %s.'

puts template % ['Oceania', 'war', 'Eurasia']

puts template % ['Luke Skywalker', 'love', 'Leia Organa']

OK, there is a nice functionality, but about POLS ?

For sure I have little experience with Ruby, but the fact, you can use the modulus operator over strings, really surprises-me.

I deal with a great assort of programming languages over 2 decades now, and never ever, applied the modulus operator over strings.

Think about this code:

puts 'abc' % 'def' # <= 'abc'

puts 'abc' % 10 # <= 'abc'

And there is another point. Negative numbers:

Witch should be the -5 % 3 result ? 2 ? -2 ?

In fact in Ruby, -5 % 3 = 1

Why ?

Some programming languages adopt the C89 standard about that subject. That is the way Ruby does:

remainder = a % n

is the same of:

remainder = a - n * floor_funtion(a / n)

where floor_function from a decimal value, returns the highest integer, less than or equal to it.

So, in Ruby this is the formula for modulus remainder result:

r = ((a) - ((n) * ((a) / (n))))

* Extra parenthesis, to put negative values easily and clear.

Ahh, take a look at those SuperRubyBoy's operators !

Sunday, November 25, 2007

Ruby, double colon !


May someone call the right phrase: “Ruby period!”

I spent at least two weeks to understand this :: operator. But why ?

If you, have no C++ or C# strong background like me, certainly the :: operator will cost you more time to learn.

First of all :: appears all around Ruby programs, and this could be a little tricky…

You have to consider just one thing:

The :: is a unary operator that allows: constants, instance methods and class methods defined within a class or module, to be accessed from anywhere outside the class or module.

Remember: in Ruby, classes and methods may be considered constants too.

You need just to prefix the ::Const_name with an expression that returns the appropriate class or module object.

If no prefix expression is used, the main Object class is used by default.

So, the operator syntax is:

ClassModule::Constant

You can see samples here.

Hope it helps You not to waste time on this subject.

Tuesday, November 20, 2007

Multiple inheritance, mixins and blog resources.

Last week, I was dealing with the use of “mixins” and its impact on method overwriting and overloading.

Some research after, could summarize on this:

  1. Multiple inheritance IS NOT supported in Ruby.
  2. Ruby supports SINGLE inheritance AND “mixins”.
  3. IF you know how (that is the question) "mixins could do almost everything multiple inheritance do, without the associated drawbacks" (Matz words).
  4. Overriding or overwriting methods, for programming purposes, means the same: Change or redefine a method that already exists in the given context.
  5. In Ruby classes are always open so, methods may be added or changed.
  6. Overloading comes from languages other than Ruby. Where you can define methods with the same name but with different argument types and quantities (signatures).
  7. Ruby is an all OOP language, for example the "+" operator is a method of the "Object" class.
  8. If you overwrite a mixed-in "+" method, you could use such modified/overwritten method on the main-object (Object class).
  9. Remember: everything in Ruby is an object.

At that point, the next step was show some code examples about that, but there is a problem. It’s not easy to put code (on a presentable way) on blogs.

On most popular blogs, there are some kinds of work to do before you can put your code there.

So, I decide not to waste time on that subject, and will select a more specialized resource to put my code and reference it here.

Suggestions welcome!

Sunday, November 4, 2007

Ruby, a programming language that don’t hurt

Thanks to Thiago Arrais and his original post about the fact that “your brain hurts when you try to learn a different thinking line”.

Most of my professional experience, more then two decades now, I deal with procedural or event driven programming languages, Structured Systems Analysis, etc.

There are the 80s and 90s… Good years, when I start to hear and read about OOP.

When 2K years came, I could't avoid OOP anymore, and my brain starts to hurt. I started with Smalltalk (big mistake), new thinking line and totally different language syntax. My brain was in constant pain.

At that point I get the OOP basic concepts, but practices those concepts with that language was not easy to me.

After that, I try Java by myself. And achieve some steps further in OOP, but need BlueJ (hiding some language specific aspects) in the beginning, to do that.

Now I’m not a newbie in OOP and programming logic, but I think if I have Ruby on the first 2K years, my brain doesn’t hurt so much.

I don’t necessary agree with Alan J. Perlis’s 19th epigram “A language that doesn't affect the way you think about programming, is not worth knowing”. For the record, I'm a big fan of the ALGOL language. It definitively affects the way I think.

But if you have to learn one, that really affects the way you think, it could be done without any hurt.

With Ruby, all the OOP concepts can be used on a very intuitive away (my viewpoint).

On my first steps using Ruby, two months by now, I have tried a lot. And most of the time I hit on the first shot.