FizzBuzz with Sather like loop

Posted by: Shugo Maeda Fri, 24 Aug 2007 23:06:00 GMT

num = (1..100).each
fizz = ([""] * 2 + ["Fizz"]).cycle
buzz = ([""] * 4 + ["Buzz"]).cycle
loop do
  n = num.next
  puts (fizz.next + buzz.next).sub(/\A\z/) { n }
end

Posted in Ruby | no comments | no trackbacks

Graceful Restart with mod_fcgid

Posted by: Shugo Maeda Fri, 24 Aug 2007 15:39:00 GMT

I tried to restart Rails application gracefully (apachectl graceful) with mod_fcgid, but I couldn't get a response on graceful restart.

The problems are:

  • mod_fcgid sends SIGTERM to FastCGI processes on graceful restart, but Rails FastCGI processes exit as soon as it's received SIGTERM (Rails FastCGI processes stop gracefully on SIGUSR1, not SIGTERM).
  • Apache child processes exit on SIGUSR1 with mod_fcgid, as soon as it's received a signal.

I created a patch to fix these problems, but I'm not sure....

Posted in Rails, mod_fcgid, Apache | no comments | no trackbacks

Sather like loop

Posted by: Shugo Maeda Fri, 24 Aug 2007 13:15:00 GMT

Sather like loop is available in the SVN head.

e1 = [1,2,3,4,5].each
e2 = ["a","b","c","d","e"].each

loop do
  p [e1.next, e2.next]
end

It's cool, isn't it?

Posted in Ruby | no comments | no trackbacks

Building MySQL/Ruby on mswin32

Posted by: Shugo Maeda Sun, 24 Sep 2006 21:30:00 GMT

I created a patch to build MySQL/Ruby on mswin32. With this patch, just type:

> ruby extconf.rb --with-opt-include=../mysql-4.1.21-win32/include \
                  --with-opt-lib=../mysql-4.1.21-win32/lib/opt
> nmake

Then you'll get mysql.so. Really easy.

If libmysql.dll is built by VC7 or later, there may be a problem with GC. It depends on whether MySQL/Ruby releases memory allocated by libmysql.dll using free()/xfree() or not.

Posted in Ruby | no comments | no trackbacks

to_json hack for Safari

Posted by: Shugo Maeda Sat, 15 Jul 2006 08:30:00 GMT

I found the reason why multibyte characters are encoded in to_json. Safari can't handle UTF-8 strings in text/javascript correctly:(

Here is new code:

class String
  JSON_ESCAPED = {
     "\010" =>  '\b',
     "\f" =>    '\f',
     "\n" =>    '\n',
     "\r" =>    '\r',
     "\t" =>    '\t',
     '"' =>     '\"',
     '\\' =>    '\\\\'
  }

  def to_json
    return '"' + gsub(/[\010\f\n\r\t"\\]/) { |s|
      JSON_ESCAPED[s]
    }.gsub(/([\xC0-\xDF][\x80-\xBF]|
             [\xE0-\xEF][\x80-\xBF]{2}|
             [\xF0-\xF7][\x80-\xBF]{3})+/ux) { |s|
      s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
    } + '"'
  end
end

I created a patch for ActiveSupport (trac of Rails is down, so I can't attach this patch to the ticket).

Posted in Rails | no comments | no trackbacks

to_json too slow

Posted by: Shugo Maeda Tue, 11 Jul 2006 03:51:00 GMT

I felt my application slow yesterday and profiled it. RJS is very useful, but it seems to be slow.

Thanks to Charlies's ruby-prof (it doesn't belongs to me any more and has fascinating call graph support), I found the bottleneck. It was Object#to_json.

The original code is here:

define_encoder String do |string|
  returning value = '"' do
    string.each_char do |char|
      value << case
      when char == "\010":  '\b'
      when char == "\f":    '\f'
      when char == "\n":    '\n'
      when char == "\r":    '\r'
      when char == "\t":    '\t'
      when char == '"':     '\"'
      when char == '\':    '\\'
      when char.length > 1: "\u#{'%04x' % char.unpack('U').first}"
      else;                 char
      end
    end
    value << '"'
  end
end

Ruby can't handle characters fast, so this code is very slow. You'd should use builtin methods such as String#gsub to handle multiple characters at once.

I put the following code into config/environment.rb, and it looks quite fast:)

class String
  JSON_ESCAPED = {
     "\010" =>  '\b',
     "\f" =>    '\f',
     "\n" =>    '\n',
     "\r" =>    '\r',
     "\t" =>    '\t',
     '"' =>     '\"',
     '\' =>    '\\'
  }

  def to_json
    return '"' + gsub(/[\010\f\n\r\t"\]/) { |s|
      JSON_ESCAPED[s]
    } + '"'
  end
end

Then I posted a patch to a related ticket.

If there is any reason to encode multibyte characters, more hacks are needed. I think the best way is to encode multiple multibyte characters at once using String#gsub and String#unpack, Array#pack.

Posted in Rails | no comments | no trackbacks

Apache::RailsDispatcher supports Rails 1.1

Posted by: Shugo Maeda Wed, 24 May 2006 13:31:00 GMT

Apache::RailsDispatcher in the SVN trunk of mod_ruby supports Rails 1.1 now:) I will release mod_ruby-1.2.6 soon.

But I can't run typo on it yet:(

Posted in mod_ruby, Rails | 2 comments | no trackbacks

RubyKaigi is Sold Out!

Posted by: Shugo Maeda Wed, 10 May 2006 21:35:00 GMT

Tickets of RubyKaigi are sold out in a few hours!

I'll talk about meta programming features of Ruby. See you in Tokyo.

Posted in Ruby | no comments | no trackbacks

PessmisticLocking

Posted by: Shugo Maeda Wed, 10 May 2006 21:35:00 GMT

PessimisticLocking provides row-level pessimistic locking using SELECT FOR UPDATE.

You can specify the new option :lock of ActiveRecord::Base.find() to lock rows:

Account.transaction do
  shugo = Account.find(:first, :conditions => "name = 'shugo'", :lock => true)
  yuko = Account.find(:first, :conditions => "name = 'yuko'", :lock => true)
  shugo.balance -= 100
  shugo.save
  yuko.balance += 100
  yuko.save
end

Or you can also use ActiveRecord::Base#lock() instead:

Account.transaction do
  accounts = Account.find(:all, :conditions => ...)
  account1 = accounts.detect { |account| ... }
  account2 = accounts.detect { |account| ... }
  account1.lock
  account2.lock
  account1.balance -= 100
  account1.save
  account2.balance += 100
  account2.save
end

The latter way may be better if you don't need lock all SELECTed rows.

Posted in Rails | no comments | no trackbacks

Japanese translation of AWDwR

Posted by: Shugo Maeda Tue, 21 Feb 2006 06:23:00 GMT

The Japanese translation of Agile Web Development with Rails will be available on Sat Feb 25:)

Japanese translation of AWDwR

Posted in Rails | no comments | no trackbacks

Older Posts

Older posts: 1 2 3