Saturday, July 30, 2011

Caller binding

One of most useful feature not present in Ruby is to get the binding of the caller of current method, to do something with its local variables.

There is an implementation in the Extensions gem, but it must be the last method call in the method, and we must use the binding within a block.

There is another implementation here, but it depends on tracing along all the code execution, compromising the performance.

However, in this answer in StackOverflow, Taisuke Yamada implemented an version of ppp.rb (what is it?) which inspired me to implement my own version of a caller_binding method. Enjoy!

#!/usr/bin/ruby
#
# (c) Sony Fermino dos Santos, 2011
# License: Public domain
# Implementation: 2011-07-30
#
# Published at:
# http://rubychallenger.blogspot.com/2011/07/caller-binding.html
#
# Inspired on:
# http://stackoverflow.com/questions/1356749/can-you-eval-code-in-the-context-of-a-caller-in-ruby/6109886#6109886
#
# How to use:
# return unless bnd = caller_binding
# After that line, bnd will contain the binding of caller

require 'continuation' if RUBY_VERSION >= '1.9.0'

def caller_binding
  cc = nil     # must be present to work within lambda
  count = 0    # counter of returns

  set_trace_func lambda { |event, file, lineno, id, binding, klass|
    # First return gets to the caller of this method
    # (which already know its own binding).
    # Second return gets to the caller of the caller.
    # That's we want!
    if count == 2
      set_trace_func nil
      # Will return the binding to the callcc below.
      cc.call binding
    elsif event == "return"
      count += 1
    end
  }
  # First time it'll set the cc and return nil to the caller.
  # So it's important to the caller to return again
  # if it gets nil, then we get the second return.
  # Second time it'll return the binding.
  return callcc { |cont| cc = cont }
end

# Example of use:

def var_dump *vars
  return unless bnd = caller_binding
  vars.each do |s|
    value = eval s.to_s, bnd
    puts "#{s} = #{value.inspect}"
  end
end

def test
  a = 1
  s = "hello"
  var_dump :s, :a
end

test

Friday, July 29, 2011

How to return from inside eval

I have a code which I need to use within eval. Sometimes I need to get out from the middle of eval code, but how?

In PHP I can use the return keyword, but it doesn't work on Ruby:

# expected to see 1, 2 and 5; not 3 nor 4; and no errors
eval "puts 1; puts 2; return; puts 3; puts 4"
  # => Error: unexpected return
puts 5

I tried with return, end, exit, break, and I couldn't get success. exit doesn't raise errors, but then I don't get the 5.

After many tries and a question in StackOverflow, I found a solution which fits best into my problem:

lambda do
  eval "puts 1; puts 2; return; puts 3; puts 4"
end.call
puts 5

This way the intuitive return keyword can be used inside eval to get out from it successfully.

You can find alternative ways at StackOverflow.

Sunday, June 5, 2011

Separate domain for desktop

Hi!

I just had a simple (maybe obvious), powerful idea for mobile web development (and for mobile users).

There's a design pattern called mobile first, which is very well shown in these slides by Bryan Rieger.

Following that thinking, we can apply it even on domain/subdomain names - not just for web contents.

E.g.: instead of having a main domain for desktop, and a separate (and longer) domain for mobiles, we can define the shorter domain for mobiles, and a separate (and longer) domain for desktops!

That is, instead of the common procedure of having:

http://example.com/ (for desktops)
http://m.example.com/ (for mobiles)


this proposal is to do:

http://example.com/ (for mobiles)
http://desktop.example.com/ (for desktops)


as desktop users can type more easily than mobile users, and desktop browsers can detect they're desktop more easily than mobile browsers can detect they're mobile (via JS, media queries, etc.).

Anyway, if your code can auto-detect (decently) a real desktop user, it can redirect the browser from the main url to the desktop one. (And the redirection is performed better on desktops than on mobiles.)

Here is my idea; I'll apply it into my projects and I'm sharing it to you to use it freely - and heavily! ;)

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!

Friday, March 25, 2011

How to make a class method private

If you want to make a class method private, you must put the private keyword inside the class << self section:

This works:
class Test
  class << self
    private

    def foo
      puts "bar"
    end
  end

  foo         #=> "bar"
end

Test.foo      #=> NoMethodError: 'foo' is a private method;
              #   That's we want!

This works, too:
class Test
  class << self
    def foo
      puts "bar"
    end

    private :foo
  end

  foo         #=> "bar"
end

Test.foo      #=> NoMethodError

And this:
class Test
  def self.foo
    puts "bar"
  end

  class << self
    private :foo
  end

  foo         #=> "bar"
end

Test.foo      #=> NoMethodError

Putting the private outside class << self doesn't work:
class Test
  def self.foo
    puts "bar"
  end

  private self.:foo     #=> Syntax error: unexpected tSYMBEG
  private :self.foo     #=> Error: undefined method "foo" for :self
  private :"self.foo"   #=> Error: undefined method "self.foo" for Test
end

And the following tests won't work, too:
class Test
  class << self
    private
  end      # by closing this block, the scope of "private" is also closed,
           # even if we reopen the block right next:

  class << self
    def foo
      puts "bar"
    end
  end

  foo         #=> "bar"
end

Test.foo      #=> "bar"

class Test
  class << self
    private
  end

  def self.foo
    puts "bar"
  end

  foo         #=> "bar"
end

Test.foo      #=> "bar"

Thursday, March 24, 2011

Ruby autoload like in PHP

(Disclaimer: this is a translation from Autoload do Ruby como no PHP, in Portuguese.)

Who has worked with OOP in PHP and starts to learn Ruby soon will miss the PHP __autoload.

In fact, Ruby has autoload, but it seems useless for a PHP programmer.

In Ruby, the autoload is for using less memory, leaving files to be loaded only when necessary. But then you need to type more than a simple require; besides specifying the filename, you need also type the constants (classnames) which are in the file. For example:

autoload :MyClass, "myclass.rb"

I guess the computers was made to help the people, and that includes the programmer. From the programmer point of view (and not from the machine's one), would be far easier to type:

require "myclass"

Unless resources are critical, the development/maintenance time is more important in this case.

In PHP, you define only once a function which will guess the filename from the classname, and then you don't worry ever more. You don't need to specify nothing!!! When a reference to "MyClass" appears, the function __autoload will convert it to a filename (e.g., "myclass.inc"; you can code __autoload with your needs) and will try to include that file. That's awesome useful!

Fortunately, Ruby is a very powerful language, and, following a tip, I made my version:

# autoload like in PHP
# (c) Sony Santos 2011
# License: Public Domain
# http://rubychallenger.blogspot.com/2011/03/ruby-autoload-like-in-php.html

# alters Object#const_missing
#
class Object

  # it's a class method, not an instance one
  class << self

    # preserves the original method
    alias_method :old_const_missing, :const_missing
    private :old_const_missing

    # redefine the method which is called on a missing const
    def const_missing(const)

      # guess a filename (use your favorite algorithm)
      filename = const.to_s.downcase

      begin
        # try to require it
        require filename

        # if it did, returns that missing const
        const_get(const)

      rescue LoadError => e
        if e.message.include? filename

          # that constant doesn't really exist; use the old method
          old_const_missing(const)

        else

          # other reason
          raise

        end
      end
    end
  end
end

About my Ruby experiences

Is Ruby easy to learn?

Er... No, it isn't.

First point: There isn't a main documentation/tutorial/reference center where you can learn step by step all the Ruby nuances, from basic to advanced techniques.

There are, in fact, many sites and books and blogs and tutorials on Ruby, and they're different from each other, and you don't know where should you start from. Only one book is not enough to read. That turns the learning by yourself into a hard task.

Second point: The basics of Ruby are easy. Classes, objects, methods... things you've seen in other languages. You can code a lot from the basics.

But what makes Ruby a powerful language, the main motivation to choose Ruby among other good languages, is not in the basics. The power of Ruby is in the Metaprogramming. It is the ability to reopen classes, even core ones, and adapt them to your suits. It is the ability to redefine methods and create methods on-the-fly, and use all flexibility of the parameters to make the best fit to your goals. It is the ability to use Ruby to create DSLs. And that is not easy.

In this blog I do not intend to teach Ruby. I will share my experiences. And, as a scientist who likes challenges, I'll make many experiments... 8^)