% notation in Ruby

Today I wanna share about the %notation I learned.

Any single non-alpha-numeric character can be used as the delimiter.

1.9.3-p327 :005 > %*lala lala "hehe"*
 => "lala lala \"hehe\""
1.9.3-p327 :006 > %&lala lala "hehe"&
 => "lala lala \"hehe\""

As you can see, * worked, & worked, so other symbol and friends will work too. Above example is using % notation to produce string, but % notation is actually more powerful than that, you can use it to produce array, regexp, shell command:


%Q{one\ntwo\n#{ 1 + 2 }}
=> "one\ntwo\n3"

%q{one\ntwo\n#{ 1 + 2 }}
=> "one\\ntwo\\n#{ 1 + 2 }"

%r/#{name}/i
=> /nemo/i

%w{one two three}
=> ["one", "two", "three"]

%i{one two three} # after Ruby 2.0
=> [:one, :two, :three]

%x{ruby --copyright}
=> "ruby - Copyright (C) 1993-2009 Yukihiro Matsumoto\n"

The post is not an exhaustive guide, but an introduction. Here’s where I copied the material from: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals#The_.25_Notation

Take a tour to % notation through the link if you haven’t, it is definitely beneficial!

If you’re familiar with test, you can try the examples written in minitest:
https://github.com/teohm/a-dip-in-ruby/blob/master/spec/percent_notation_spec.rb

It’s from this blog post: http://teohm.github.io/blog/2012/10/15/start-using-ruby-percent-notation/

It’s a tiring day… It’s time to get some rest! Good night 🙂

Ruby’s alias_method

Today I learned about an interesting method in Ruby alias_method, this method can be used to refer to an old method in a module. The documentation is here: http://apidock.com/ruby/Module/alias_method. But at first glance, I couldn’t understand what it’s used for. So this simple post will illustrate a little.

Let’s say we have a module initially:

module Mod
  def print_asdf
    puts "lalalala"
  end
end

We can use it like this:

irb> include Mod
 => Object
irb> print_asdf
  lalalala

Later we decided to reopen the module and overwrite the function to add something:

module Mod
  def print_asdf
    print_asdf
    puts "changed"
  end
end

It’s just like calling the superclass method when we’re doing inheritance in OOP, but for this case we can’t use super.print_asdf, if we call the above method, we’ll run into error:

irb> include Mod
irb> print_asdf
SystemStackError: stack level too deep
   from /Users/tanjunrong/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/irb/workspace.rb:80
Maybe IRB bug!

That’s because it’s running recursively! This can be solved by alias_method:

module Mod
  alias_method :hey, :print_asdf

  def print_asdf
    hey
    puts "hehe"
  end
end

Now we can use it properly:

irb> include Mod
irb> print_asdf
  lalalala
  hehe

Simple post. Bye!

Continue a task using Thread after render has returned

As rails is an opinionated framework, it uses the MVC pattern. Whenever it receives a request, it will go through a controller and the controller will render a page to be returned.

def index
    render :action => :index
end

However, sometimes we have to run a longer task.

def index
    # some time consuming task
    render :action => :index
end

When we met with this situation, this browser will be in the loading-forever mode, and the server might even timeout the connection. One of the way to solve it is to render a view for the user first, telling them “your request is running at the background”, then we continue on our long process. So this is how it’s done:

def index
    Thread.new do
        # some time consuming task
    end
    render :action => :index
end

This way, the web app will spawn another thread for the long task, so the view will be returned to the user first, and the long task will still be executed at the background.

However, if the long running task is too heavy, we can use delayed_job or resque to queue up the job for background execution.

Transaction class method of Active Record

Today I’m working on my rails project at work as usual, and met with a scenario that needs me to update a model by deleting and saving it in one go. So I learned that there is  a way of doing it by using the transaction class method from ActiveRecord.

It is very simple to use, you simply need to place the desired active record functions as a block argument into the transaction method like such:

Account.transaction do
  balance.save!
  account.save!
end

By using this way, SQL statements will only become permanent if they can all succeed as one atomic action, so it is safe to make a series of active record interactions without worrying that it will fail half way, and left you in an undetermined and hard-to-debug state.

How to leave a task behind on the server to run

Recently, I need to run a huge crawling tasks on the server side, and since I couldn’t leave my ssh connection on and run the task for 100 hours, what if I tripped over the router and got discounnected?

So I considered delayed_job on Rails, but I ran into some problems that I couldn’t solve, so I found another work around to this problem which might be useful in other cases. The solution is using tmux or screen:

http://stackoverflow.com/questions/11190648/how-to-keep-rails-command-from-rails-console-running-after-ssh-client-putty-cl

Here’s how to do it:

  1. ssh into_your_server
  2. tmux
  3. (you should see the tmux screen)
  4. execute whatever you want to run here
  5. press Ctrl-b then d
  6. (you should be detached from the tmux now)
  7. ps aux |grep tmux (you should be able to see tmux is still running your task)
  8. (reattach with your task by) tmux attach-session

Command not found in Capistrano

I learning how to deploy with Capistrano, but I ran into problem quickly, so here’s how I solve it:

1. rake is not found

  • solution: add this into deploy.rb
  • set :rake, ‘bundle exec rake’

2. bundle is not found

  • solution: run this using “cap shell”
  • gem install bundler

3. PATH problem, when running this in Cap shell:

cap> ruby -v
*** [err :: something.com] sh: 1:
*** [err :: something.com] ruby: not found

  • Solution: add this into deploy.rb
  • set :default_environment, {‘PATH’ => “/home/ubuntu/.rvm/gems/ruby-1.9.3-p327/bin:/home/ubuntu/.rvm/gems/ruby-1.9.3-p327@global/bin:/home/ubuntu/.rvm/rubies/ruby-1.9.3-p327/bin:/home/ubuntu/.rvm/bin:$PATH”}
  • * you can ssh into your server and find out the path by doing “echo $PATH”

Using Module as Namespace

When I was reading the book Metaprogramming Ruby, I came across how to use Module as a namespace and thought it’s pretty useful. So I’m sharing it in this post:

Consider the following:

CHILI_MULTIPLIER = 0
module SuperSpicy
   CHILI_MULTIPLIER = 99
end

print "CHILI_MULTIPLIER : ", CHILI_MULTIPLIER,"\n"
print "SuperSpicy::CHILI_MULTIPLIER : ", SuperSpicy::CHILI_MULTIPLIER,"\n"

Result:

CHILI_MULTIPLIER : 0
SuperSpicy::CHILI_MULTIPLIER : 99

When we’re inside a module, we can still refer to the outer Constant by adding :: in front of the Constant.

CHILI_MULTIPLIER = 0

module SuperSpicy
   CHILI_MULTIPLIER = 99

   class Curry
      print "CHILI_MULTIPLIER : ", CHILI_MULTIPLIER.to_s ,"\n"
      print "::CHILI_MULTIPLIER : ", ::CHILI_MULTIPLIER.to_s, "\n"
   end
end

Result:

CHILI_MULTIPLIER : 99
::CHILI_MULTIPLIER : 0

If you want to find out about how deep you’ve gotten into, you can use Module.nesting(), try this:

print "[outter most] Module.nesting() : ", Module.nesting(), "\n"
   module SuperSpicy
   print "[inside SuperSpicy] Module.nesting() : ", Module.nesting(), "\n"
   class Curry
      print "[inside Curry] Module.nesting() : ", Module.nesting(), "\n"
   end
end

Result:

[outter most] Module.nesting() : []
[inside SuperSpicy] Module.nesting() : [SuperSpicy]
[inside Curry] Module.nesting() : [SuperSpicy::Curry, SuperSpicy]

That’s it 🙂