Monday, April 11, 2011

Ways to map hashes

In Ruby, Hashes haven't the map or map! method; it's for Arrays.

However, sometimes we need to do something with the keys or the elements of a Hash. Here I show some ways to do that:

1. Through each_key or each_pair (first natural options, from reference):
hash.each_key  { |k| hash[k] = some_fun(hash[k]) }
hash.each      { |k, v| hash[k] = some_fun(v) }
hash.each_pair { |k, v| hash[k] = some_fun(v) }

2. Through merge (inspired here):
hash.merge(hash) { |k, ov| sume_fun(ov) }

3. Here a way to modify the keys (from here):
Hash[*hash.map{|key,value| [key.upcase, value]}.flatten]

4. A way to work with hashes sorted by keys (which I published here):
hash.keys.sort.each { |k| puts k + " => " + hash[k] + "
\n" }

Tuesday, April 5, 2011

How to run Ruby CGI scripts in Windows 7 with XAMPP

I use Ubuntu to develop my apps, but sometimes I need to run scripts in windows.

In a computer with Windows 7, I've installed Ruby and XAMPP. It runs PHP script very well, but when I tried to run a Ruby CGI script, I got the error:

Couldn't create child process: 720002

It's due to the "shebang" first line of the script:

#!/usr/bin/ruby

In my local installation, ruby is in:

C:\ruby\bin\ruby.exe

That's not much different from the linux path. I solved the problem by creating a symbolic link usr pointing to ruby at root directory. To do that, run cmd as Administrator and type:

c:
cd \
mklink /D usr ruby

That was enough to run my scripts. :)

Sunday, April 3, 2011

Two ways to write an "increment" method

1. As I did in another post:
inc = lambda do |x|
  eval "#{x} += 1"
end

a = 5

inc[:a]

puts a       #=> 6

2. Inspired here:
def inc(&blk)
  eval "#{yield} += 1", blk
end

x = 5
inc {:x}

puts x       #=> 6

Swapping variables

Today I was learning about binding, and the example showed in that page is how to use binding to swap variables.

The text ended up with
swap(ref{:a}, ref{:b})

However, I show here a less verbose (and simpler) swap (without binding, references, etc.):

swap = lambda do |x, y|
  eval "#{x}, #{y} = #{y}, #{x}"
end

a = 'hihaha'
b = 33

swap[:a, :b]

puts a         #=> 33
puts b         #=> 'hihaha'

I guess the former example is still valid as didatic text about binding.