Dienstag, 18. Juni 2013

Testing a rounding problem

Floating numbers are characterized by their precision. That's why floating numbers are always inexact though a specification for calculating that kind of numbers should define its precision. It can be one digit up to 15 digits or whatever.
Anyway. The question is, how to test the defined precision? In the following example I expect a precision of 2 digits. For understanding reasons I show the code first followed by the test. The class is simple circle stuff with a method, which returns the calculated area:
class Circle
  attr_accessor :radius
  def initialize radius=1
    @radius = radius
  end
  def area
    radius * radius * Math::PI
  end
end
There are the 2 accessors for the instance variable "radius" and the constructor "Circle#initialize" with a default parameter for a unit circle. And at least there is the algorithm for calculating the area of a circle in "Circle#area", which returns the most possible precise result. The RSpec test is:
# circle_spec.rb
require './circle.rb'
describe Circle do
  describe "#area" do
    it "should calculate the area of a circle" do
      radius = 2
      circle = Circle.new radius
      circle.area.should be_within(0.01).of(12.56)
    end
  end
end
"Matchers#be_within" ensures that the precision should be 2 digits, nevertheless the method returns a more precise number.

Supported by Ruby 1.9.3

Mittwoch, 29. Mai 2013

Respond to method missing

You have to deal with dynamic method calls and somebody threw an "Implement method_missing" at you?
You google how to do it and maybe find an article like "method_missing, baby!". You code what you gotta code...
But that's only half of the truth. You probably missed to "respond_to?":
class Person
private
  def method_missing method_name, *args
    if %w(runs walks goes drives).include?(method_name.to_s)
      puts "#{self.class} #{method_name}."
    else
      super
    end
  end
end
which means, you broke the POLS (Principle Of Least Surprise):
person = Person.new
person.respond_to? :runs # => false
person.runs # => "Person runs."
Curious! An object, which claims not to respond to a receiver, but instead seem to respond? None would expect such behavior. The solution is to overwrite Person#respond_to? likewise:
class Person
  MOTIONS = %w(runs walks goes drives)
  def respond_to? method_name
    MOTIONS.include? method_name.to_s
  end

private
  def method_missing method_name, *args
    if MOTIONS.include?(method_name.to_s)
      puts "#{self.class} #{method_name}."
    else
      super
    end
  end
 end
and accordingly:
person = Person.new
person.respond_to? :runs # => true
person.runs # => "Person runs."
If it walks like a duck and if it quacks like duck, it is a duck. Ruby duck typing.
Lastly I want to point to another great article about the Principle Of Least Surprise: The Tao Of Programming. Funny.

Supported by Ruby 1.9.3

Montag, 13. Mai 2013

method_missing, baby!

Meta programming in Ruby is a pleasure. And there are a lot of reasons for. One is method_missing.
A famous example of its "magic" is ActiveRecord and the dynamic finders in Ruby On Rails (active _record/dynamic_matchers.rb).
The approach is simple. Every time an object method was called, which is not defined, (or better a receiver gets an unknown message), Delegator#method_missing cares about it. You can overwrite method_missing in your class. And that's the hook that can be used for dynamics. And it IS used widely.
I demonstrate how to, in a very simple example.
The story is: I want people to move in different ways:
class Person
private
  def method_missing method_name, *args
    if %w(runs walks goes drives).include?(method_name.to_s)
      move method_name
    else
      super
    end
  end

  def move kind
    puts "#{self.class} #{kind}."
  end
end
There is no public method defined in the class "Person". It looks like no person can move in any way. But:
Person.new.runs
returns:
Person runs.
So what happened?
A new person object was instanciated and an message ("runs") was sent to it. Simply because the message is not defined, method_missing is sent instead. Please read the overwritten Person#method_missing carefully. If the message ("runs") is one of "runs", "walks", "goes" or "drives" the private method Person#move is sent internally. That's all. And that's why:
person = Person.new
person.walks
person.drives
returns:
Person walks.
Person drives.
And that's also why:
Person.new.swims
still calls the super method_missing:
undefined method 'swims' for # (NoMethodError)
Method missing, baby!

Supported by Ruby 1.9.3

Montag, 6. Mai 2013

Boolean method parameter assignment in Ruby

At first: prevent using boolean parameters in method definitions.
But let's assume you have to call a method that expects a boolean parameter like:
class Human
  def go backward=false
    puts "#{self.class} is going " + 
      (backward ? "backward" : "forward")
  end
end
A human can go forward and backward.
We want a human to go backward. If you would code it this way:
human = Human.new
# human goes backward
human.go true
please go on reading, because there is something to improve. At first the output is as expected:
Human is going backward
The code works but you have to agree, that "human.go true" is not readable (that's why there is a line of documentation). But we can improve the readability:
human = Human.new
human.go :backward
also results in:
Human is going backward
In Ruby a Symbol and all objects except instances of Nil and False class are true. Besides using an expressive Symbol can save the line of documentation, because the code documents itself. Awesome! Going forward could be default or explicit:
human = Human.new
human.go # default forward
human.go not(:backward) # explicit
The "not" before the Symbol inverts the assigned parameter. You also could use a bang ("human.go !:backward"). The result:
Human is going forward
Human is going forward
Though I'd prefer having a well designed API method ;-)

Supported by Ruby 1.9.3

Freitag, 3. Mai 2013

Ruby iterators

Ruby iterators are very sweet. But sometimes some of them seem to be ignored. And there is only reason I can imagine: they are not known. Instead, "Enumerable#each" is used as the universal weapon. No it's not. It's worth to read the API of Enumerable before coding an odd iteration. This is about your reputation. Let's start.

Use Case: How to accumulate a collection of items?

Enumerable#inject and its alias Enumerable#reduce iterate over all items and applies a binary operation to a memo (which contains the accumulated temporary value). A simple accumulation:
puts [2,3,4,5].inject { |sum, i| sum += i }
If a block is passed like here, the first parameter is the memo and the second is item itself.
The result is:
14
You also can set an initial value for the memo (sum):
puts [2,3,4,5].inject(1) { |sum, i| sum += i }
and the result is:
15
There is also a shorter way of the same accumulation by passing a symbol instead of the block. Then the items are sent to that method (in this case "+") of memo. Take a look:
puts [2,3,4,5].inject(1, :+)
with the same result:
15

Use Case: How to copy a collection and manipulate its items?

Enumerable#collect and its alias Enumerable#map iterate over all items like Enumerable#inject does, but applies an operation to each item (and that's the important difference). For example I could want to increment every number:
numbers = [2,3,4,5]
puts numbers.collect { |number| number += 1 }.inspect
Therefore it returns a new collection containing the modified items:
[3, 4, 5, 6]

Please note that the original collection "numbers" still contains the original items.

Use Case: How to search a collection for the first proper item?

Enumerable#find finds the first item in a collection for which the block returns true. For example I would want to find the first even number in a collection of numbers:
puts [3,4,2,5,1].find { |number| number.even? }
and found:
4

Please note, that 2 is also even but wasn't picked, because its index in the collection is higher than the index of 2.

Use Case: How to search a collection for every proper item?

Enumerable#find_all and its alias Enumerable#select are kind of similar to Enumerable#find, but they find ALL items in a collection for which the block returns true. That's why both return an array.
The same example collection of names:
puts [3,4,2,5,1].find_all { |number| number.even? }.inspect
finds not only 2, but also 4:
[4, 2]

Use Case: How to search a collection for every improper item?

Enumerable#reject is opposite to Enumerable#find_all. It finds all items for which the block returns FALSE. To me it exists more for readability reasons. But in the context of the same numbers example, which I used before, it would look like:
puts [3,4,2,5,1].reject { |number| number.even? }.inspect
copies the original array without the even numbers:
[3, 5, 1]

Use Case: How to search a collection for the item having the minimum value?

Enumerable#min_by can be confused with Enumerable#find, since it seems to do the same job. But a closer look, highlights that Enumerable#min_by is a more concise iterator for just value comparison. The same "even number" example:
puts [3,4,2,5,1].min_by { |number| number % 2 }
This time I determine the first even number with the modulo-2-algorithm (Numeric#even? also does modulo 2 internally). The first number with result 0 (minimum number) is picked for return:
4
You definitely would go for Enumerable#find to find the first even number, but I'd like to mention another example to illustrate the concision of Enumerable#min_by:
puts %w(Bob Al Susan).min_by { |name| name.length }
finds the shortest name:
"Al"

Use Case: How to search a collection for the item having the maximum value?

Enumerable#max_by is the sibling of Enumerable#min_by. It finds the first item having the maximum value:
puts %w(Bob Al Susan).max_by { |name| name.length }
finds the longest name:
"Susan"

Use Case: How to search a collection for the items having the minimum or maximum value?

Enumerable#minmax_by is the third sibling in family. It returns an array with 2 elements. One for the item having the minimum value and one for item having the maximum value:
puts %w(Bob Al Susan).minmax_by { |name| name.length }
finds the shortest and the longest name:
["Al", "Susan"]

Use Case: How to select all items of a collection as long as they are proper?

Enumerable#take_while iterates over a copied collection and keeps every item, for which the block returns true. If the first item is not proper due to the return value of the block, the iteration stops and returns the result array.
The names example:
puts %w(Bob Al Alexander Susan).take_while { |name| name.length < 8 }.inspect
stops during the third iteration ("Alexander" consists of 9 letters) and returns:
["Bob", "Al"]
Please note, that the fourth item ("Susan") wasn't selected, though it would satisfy the condition. And that is the difference to Enumerable#find_all.

Use Case: How to remove all items in a collection as long as they are proper?

Enumerable#drop_while iterates over a copied collection and removes every item from the new array, for which the block returns true. If the first item is not proper due to the return value of the block, the iteration stops and returns the result array.
The names example:
puts %w(Bob Al Alexander Susan).drop_while { |name| name.length < 8 }.inspect
stops during the third iteration ("Alexander" consists of 9 letters) and returns:
["Alexander", "Susan"]

Supported by Ruby 1.9.3

Sonntag, 28. April 2013

Lambda is not a Proc

I guess you already know about Procs. The lambda in Ruby is also a closure. Therefore, it encapsulates logic which can be executed at the time it is encountered. It even an be put into a particular context by passing it to a function. So far nothing new.
That's why I start with explaining the lambda and later compare with the Proc.
A simple lambda:
my_lambda = lambda { puts "A lambda" }
my_lambda.call
returns:
A lambda
Sure, you can pass a parameter:
my_lambda = lambda { |param| puts "Parameter: #{param}" }
my_lambda.call(1)
returns:
Parameter: 1
And yeah you can also pass more than one parameter like:
my_lambda = lambda { |p1, p2| puts "Parameters: #{p1}, #{p2}" }
my_lambda.call(1, 2)
returns:
Parameters: 1, 2
You also can pass the lambda to a method for some reasons:
def my_function(block)
  puts "before lambda"
  block.call
  puts "after lambda"
end
my_lambda = lambda { puts "inside lambda" }
my_function my_lambda
returns:
before lambda
inside lambda
after lambda
Though there are not many reasons for passing logic to an object method without using data of that object. You would more often want to "send logic" to an object for dynamically using its data. Then you pass a parameter like:
def my_function(block)
  number = 0
  block.call(number)
end
my_lambda = lambda { |p| puts "inside lambda: #{p += 1}" }
my_function my_lambda
returns:
inside lambda: 1
At this point I note an essential property of closures. They automatically carry with them the bindings from the code location where they were created.
 
word = "Foo"
def redefine_word(block)
  word = "Bar"
  puts word
  block.call
end
redefine_word(lambda { puts word })
You really have to take care of the scope, when you send a block to a function. Consider the output:
Bar
Foo

The difference between lambda and Proc

There is another exciting detail I want to put the finger on. Control keywords like return, raise, break, redo, retry do NOT have any impact on the further execution. And that's an important difference to Procs. A lambda example:
 
def my_method
  puts "before lambda"
  my_lambda = lambda do
    puts "inside lambda"
    return
  end
  my_lambda.call
  puts "after lambda"
end
my_method
returns:
before lambda
inside lambda
after lambda
And now the same snippet with a Proc:
 
def my_method
  puts "before Proc"
  my_proc = Proc.new do
    puts "inside Proc"
    return
  end
  my_proc.call
  puts "after Proc"
end
my_method
returns:
before Proc
inside Proc
Boom! The "return" inside the Proc prevents executing all following logic (line 8 of "my_method"). Good to know, isn't it? Another important difference concerns the parameters of the block. Lambdas are strict:
my_lambda = lambda { |p1, p2| puts "Parameters: #{p1}, #{p2}" }
my_lambda.call("One")
ends up in an exception:
wrong number of arguments (1 for 2) (ArgumentError)
But a Proc is liberal:
my_proc = proc { |p1, p2| puts "Parameters: #{p1} and #{p2}" }
my_proc.call("One")
returns:
Parameters: One and
Keep the differences in mind, when you choose a Proc or a lambda for closuring.

Supported by Ruby 1.9.3

Mittwoch, 20. Februar 2013

The quick Proc

In the previous post Yield your block in Ruby I described how to code a block and its short cut "yield". You may have noticed that another kind of closure, the Proc. The goal behind is the same as the already explained block. But you will get into the situation to save a block for later dynamic use. I used a Proc the first time in my very first Ruby On Rails project.
That's why I also explain the Proc in a Rails example now.
Let's assume a model Machine:
class Machine
  attr_accessor :in_progress
  attr_accessible :name
  validates :name, :presence => true, :unless => Proc.new { |machine| machine.in_progress.blank? } 
end
having the accessor methods generated through "attr_accessor". Furthermore there is the model attribute "name" for the machine name. I want the machine validate its name for presence only in the case of the machine was already started.
That's why there is the third call "validates". And it is only called, when the :unless key contains a false. Since the validation call is dynamic, there is a Proc assigned. It executes its code not before the validation call and can return true or false depending on the value of the instance variable @in_progress.
I agree, the logic of the Proc also could be put into an instance method, say "in_progress?" (as it would be generated by Rails, if it was a model attribute).
But why should I? I only need the logic once and this way it is more readable, because it is located next to the key.
So when do I use a Proc?
I do, when some logic should be called dynamically and not be put into a method for some reasons.

Supported by Ruby 1.9.3, RubyOnRails 3.1

Montag, 11. Februar 2013

Yield your block in Ruby

In Ruby there are some topics which are not often discussed and even some developer not really know about. One of them are closures.
The Ruby closures are called blocks, Procs and lambdas. They enclose logic, which can be invoked outside of its immediate scope.
Every Ruby developer already used a block when running the well known Array#collect! or Hash#select!. An easy to understand (and 100% true) example:
languages = ["Ruby", "Python", "Javascript"]
languages.collect! do |language|
  "#{language} is awesome!"
end
The introduction so far. But how does the Proc behind (e.g. Array#collect!) work, how to do something similar and when to use it?
To illustrate the functionality of such closure I start with the Proc itself:
class Array
  def power!(&block)
    self.each_with_index do |number, index|
      self[index] = number * number
      block.call(self[index])
    end
  end
end
I re-opened the Array class and added the power! method. I sticked to Ruby conventions and put a bang at the end (if you don't know why, read about the bang convention). The method itself expects a block (or rather enclosed logic) to be passed. That is why there is an ampersand before the block parameter. Inside it only iterates over its items, squares each and calls the block on the result. Quick & simple.
The Proc is called:
numbers = [1, 2, 3, 4]
numbers.power! do |number|
  puts number
end
and prints:
1
4
9
16
 => [1, 4, 9, 16]
Well. Simple but pretty static. The call of "puts" is injected into the scope of the method "power!" by putting it into the block. Let's enhance the same example and rename the method:
class Array
  def iterate!(&block)
    self.each_with_index do |number, index|
      self[index] = block.call(number)
    end
  end
end
The method "iterate!" is pretty comparable to the stuff Array#collect! does. It iterates over each item and stores the result of the called block. In a conclusion "iterate!" offers much more dynamics. We also could square:
numbers = [1, 2, 3, 4]
numbers.iterate! do |number|
  number * number
end
There is a keyword known for calling the block. Its name is "yield". Using it you don't pass a "&block" to the method. The Array#iterate! would look like:
class Array
  def iterate!
    self.each_with_index do |number, index|
      self[index] = yield(number)
    end
  end
end
Finally I want to point out that you also can pass as much as parameters as you need to your closure. An example with two parameters would be:
class Array
  def iterate_with_index!(&block)
    self.each_with_index do |number, index|
      self[index] = block.call(number, index)
    end
  end
end
and calling it:
numbers = [1, 2, 3, 4]
numbers.iterate_with_index! do |number, index|
  puts index
end
returns:
0
1
2
3
 => [nil, nil, nil, nil]
I use blocks to keep my code DRY and to achieve more readability. And there will be a point you can't ignore them.

Supported by Ruby 1.9.3

Mittwoch, 23. Januar 2013

Ruby On Rails calling SAP

Some years ago I had to tap several RFC of SAP. Believe me, communicating with SAP is no fun (in fact SAP is the acronym for Shitty Awful Pain or more seriously Slow Account Program), but without the RFC connector of Piers Harding it would have been impossible. Since SAP is a so called monopolist in the ERP layer, you might have to deal with it and know how to do.
First step is to download the current sapnwrfc of Piers:
user$ curl -o sapnwrfc-0.26.tar.gz http://www.piersharding.com/download/ruby/sapnwrfc/sapnwrfc-0.26.tar.gz
untar it:
user$ tar -xzf sapnwrfc-0.26.tar.gz
build a gem:
user$ gem build sapnwrfc.linux.gemspec
and install the generated gem. The name depends on the version and architecture of your machine. For example:
user$ gem install sapnwrfc-0.26-x86_64-darwin-11.gem
Check, if it is working in your irb:
require 'sapnwrfc' 
Preparations finished.
The basic requisite is an existing RFC module you want to interact with and to know the specific connection parameters. Put them into a configuration file (config/sap.yml):
ashost: your.sap_host.com
sysnr: "00"
client: "510"
user: your_user
passwd: your_pass
lang: EN
trace: 1
Furthermore you have to know the SAP RFC you want to call. In my case it is the fictive RFC "zEquipments". I create a model (models/equipment.rb) as the calling Ruby endpoint:
require 'sapnwrfc'
SAPNW::Base.config_location = "#{Rails.root}/config/sap.yml"
SAPNW::Base.load_config

class Equipment
private
  def self.connect(&block)
    rfc_connection = SAPNW::Base.rfc_connect
    discovered_connection = rfc_connection.discover("CRHD")
    rfc = discovered_connection.new_function_call
    block.call rfc
    rfc_connection.close
  end

public
  def self.find_all_by_site site
    equipments = []
    self.connect do |rfc|
      rfc.EQUIPMENT_PARAMS {
        "WERKS" => site.to_s
      }
      rfc.invoke
      rfc.RETURN.each do |equipment|
        equipments << equipment["ARBPL"].strip
      end
    end
    equipments.uniq!
  end

  def self.find_by_objid objid    
    name = nil
    self.connect do |rfc|
      rfc.EQUIPMENT_PARAMS {
        "ARBPL" => objid.to_s
      }
      rfc.invoke
      name = rfc.RETURN.first["ARBPL"].to_s.strip
    end
    name
  end
end
The first line is self-explanatory. The two following lines load the SAP configuration initially. I first coded a separate private class method for connecting to the SAP system, because I use the logic for connecting twice. The first public class finder method "find_all_by_site" expects the name of the site where the equipments are located in. It connects to the RFC and passes the site parameter. The result collects the names of the found equipments and removes all duplicates (you never know with SAP).
Please note the implemented block for connection. I'll cover the use of closures in the post "Yield Your Block in Ruby".
The second public class finder method searches for a certain equipment having a specific OBJID (the unique identifier for every equipment in SAP) and returns its name.
Conclusion: 2 finder methods calling the same SAP RFC with different parameters returning a collection of equipment names or a certain equipment name.

Supported by Ruby 1.9.3, RubyOnRails 3.1 and SapNwRfc 0.26