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.

Tuesday, March 29, 2011

Two ways to simplify Array blocks in Ruby

1. If you have a block of the form { |v| v.mtd }:

ary.each { |v| v.mtd }          # normal way
ary.each(&:mtd)                 # simpler way

# Example:
ary = %w(abc def ghi jkl)
ary.each(&:upcase!)             # same as ary.each { |v| v.upcase! }

That works for other Array methods, like map. More on it.

2. If you have a block of the form { |v| mtd v }, and the method mtd does the same thing with all parameters:
ary.each { |v| mtd v }          # normal way
mtd *ary                        # simpler way

#Example:
ary = %w(abc def ghi jkl)
puts *ary                       # same as ary.each { |v| puts v }

See more on it.

Monday, March 28, 2011

Why Ruby has rand(x) instead of x.rand

When I was choosing a new language to work with after PHP, I was considering Python and Ruby. Both claim to be pure object-oriented languages, but some argue that Ruby is "more" OO because Python has things like abs(-3), which in Ruby is -3.abs (ie, it makes more sense if abs is a method of numeric objects).

However, recently I was faced with rand(1000). "Gosh! Wouldn't it be 1000.rand?! Why Ruby could be so 'not-OO'?"

After thinking for a while and read the rand documentation, it becames clear to me that the original purpose of rand is to give us a (pseudo) random float number between 0 and 1. And that isn't a numeric method; there's no sense in saying 693.rand to get a random number between 0 and 1. So it was implemented in module Kernel, like a procedural function accessible anywhere. Then, to increase the usability of rand, they decided to take an optional parameter to return a random number between 0 and it, if it is supplied. IMHO, that's why Ruby has rand(x) instead of x.rand.

Anyway, you can easily implement x.rand in Integer class. ;-)

Sunday, March 27, 2011

Class Variable to increment Fixnum objects

Anyone who starts to play with Ruby Metaprogramming soon is faced with the Fixnum increment problem.

Fixnum has no pre/post self-increment/decrement operator/method.

Some nice day I innocently tried to do i.succ!, guessing "that obviously exists". I was surprised when I got an error. Well, I thought, in Ruby it's simple: it's just to code:

class Fixnum
  def succ!
    self.replace succ
  end
end

(I'd to use self.replace in String class recently.)

Then I was shocked: replace is not an Object method; it's a String (and some other classes') method, and it's not available to Fixnum (and some other classes).

But then, "how can we (or anyone) implement such methods into Fixnum?" A powerful language like Ruby could not be that restricted!

Since we see many magic codes using Ruby Metaprogramming, I was decided to find a way.

As I was learning Ruby, I understood that if Ruby hasn't something, you can implement it. E.g.: Ruby has not the "with" keyword, like Pascal. That's not a problem, as you can implement it. So I thought there would be a way to do a self-increment method for Ruby integers.

It isn't really necessary, since we can use i += 1. But then I had adopted the challenge. Now I wouldn't stop anymore. Oh, no!...

One argument for not having the ++ operator in Ruby is: a symbol refers directly to the object, and not to the variable which contains the object. So, if i is 1, trying to do i++ is the same as trying to do 1++, which would turn the value of the number 1 into 2, and 1 woudn't be 1 anymore.

Personally I don't agree with that argument, because you can do "i += 1" and you can't do "1 += 1"; so, I think would be possible to do "i++" not being the same as doing "1++". Anyway I agree with other arguments, like: it's not the Ruby way to code; it can obfuscate the code; it can cause confusion about what is going on in codes like "a[++i] = i++" etc.

I tried many things. The first try that worked was a lambda method to increment a variable through its symbol:

inc = lambda do |x|
  eval "#{x} += 1"
end

a = 5

inc[:a]

puts a       # => 6

(I'd tried "def inc" to do the same in main:Object and in class Symbol, but inside a "def" eval can't access external variables.)

But that is not like doing "a.inc". So I went on, and on, and on, and some other nice day I finnaly got it! And so I decided to create this blog! (Yes: this post is the reason for which I created this blog!) I used a class which I named "Variable", because it contains the object instead of being the object itself. Here's it:

class Variable

  def initialize value = nil
    @value = value
  end

  attr_accessor :value

  def method_missing *args, &blk
    @value.send(*args, &blk)
  end

  def to_s
    @value.to_s
  end

  # here's the increment/decrement part
  def inc x = 1
    @value += x
  end

  def dec x = 1
    @value -= x
  end

  # pre-increment ".+" when x not present
  def +(x = nil)
    x ? @value + x : @value += 1
  end

  def -(x = nil)
    x ? @value - x : @value -= 1
  end
end

a = Variable.new 5

# normal + operator
puts a + 3           # => 8
puts a               # => 5
puts a.inc 2         # => 7
puts a               # => 7
puts a.dec           # => 6
puts a.dec           # => 5

# pre-increment + operator,
# (for those who doesn't like to type "inc")
puts a.+ * 2         # => 12: a turns into 6, which is doubled
puts a               # => 6
puts a.value.class   # => Fixnum

# puts a while a goes to zero
puts a while a.-> 0

(About the last line, see more on "goes to" operator. :)

I think it's not soooo useful, but if you can do something interesting with it, please tell me! :)

After doing that, I found an elegant way to do similar behavior by using delegation.

Enjoy!