Wayne’s Tech Blog

%w(Rails Ruby Coldfusion Oracle Javascript Hack).each_day{…}

今天想在项目中应用Cucumber进行测试,感觉不错,可惜在命令行窗口中输出的结果中文全变成了乱码,完全影响测试结果的可读性(Cucumber的强项就在此啊)。于是开始寻找解决的方法。

1、最先想到的是cucumber输出的是UTF-8编码,而且整个Rails站点的环境也都是UTF-8了,输出到DOS命令行,显然会出现中文乱码。

于是Google到http://www.javaeye.com/topic/120172,里面提出的解决方法是使用 chcp 65001修改cmd的内码页为Unicode。直接输入unicode没问题了,可惜这种方式执行ruby代码会出现Bad file descripto错误!其原因大致是出在ruby端了。

无奈只能另寻他路。

2、换一种思路,考虑到ruby的动态特性,想到覆盖Kernel中的print和puts方法,将输出的内容转换为GB2312,再输出岂不解决问题?

于是翻阅cucumber的代码,发现此为正解,而且cucumber已经考虑到这种情况,有文件cucumber-0.1.16\lib\cucumber\formatters\unicode.rb为证。

可惜很遗憾,cucumber中考虑到需要转换的内码从1251到1252(WinLatin1),没有考虑到中文windows中内码代码为936,因此转换UTF-8输出内容的功能没有启用。另外是不是把936加上就解决问题了呢?测试过好像不行,原因就没深究了。

codepages = (1251..1252)
if codepages.include?(codepage)
Cucumber::CODEPAGE = “cp#{codepage}
..
最终的解决方法是讲unicode.rb修改至如下:
# Require this file if you need Unicode support.
require ‘cucumber/platform’
require ‘cucumber/formatters/ansicolor’

$KCODE=’u’ unless Cucumber::RUBY_1_9

#if Cucumber::WINDOWS_MRI && `chcp` =~ /Active code page: (\d+)/
#codepage = $1.to_i
#codepages = (1251..1252)

#if codepages.include?(codepage)
Cucumber::CODEPAGE = “GB2312″ #强制将输出内码为GB2312

require ‘iconv’
module Kernel
alias cucumber_print print
def print(*a)
begin
cucumber_print *Iconv.iconv(Cucumber::CODEPAGE, “UTF-8″, *a)
rescue Iconv::IllegalSequence
cucumber_print(*a)
end
end

alias cucumber_puts puts
def puts(*a)
begin
cucumber_puts *Iconv.iconv(Cucumber::CODEPAGE, “UTF-8″, *a)
rescue Iconv::IllegalSequence
cucumber_puts(*a)
end
end
end
#end
#end

  • 1 Comment
  • Filed under: 未分类
  • Rails中直接使用OCI8的Connection

    为了提高执行效率,希望能够跳过ActiveRecord的CRUD直接调用Oracle的PLSQL,于是开始寻找怎么在Rails里面直接调用OCI8的Connection对象。因为ActiveRecord肯定是使用OracleAdapter来进行连接的,OracleAdapter中使用的就是OCI8。为什么不直接使用OCI8.new呢?很显然这样会创建一个新的至Oracle的连接,浪费开销。

    翻遍了activerecord-oracle-adapter的代码,干脆在OracleAdapter类中添加一个自定义的方法oci_connection解决问题:

    module ActiveRecord
      module ConnectionAdapters #:nodoc:
        class OracleAdapter < AbstractAdapter
          def exec(sql, *bindvars, &block)
            @connection.exec(sql, *bindvars, &block)
          end
    
          def oci_connection
            @connection
          end
        end
      end
    end
    最后准备结束时,突然发现:
    conn = ActiveRecord::Base.connection.raw_connection
    
    参见:http://ruby-oci8.rubyforge.org/en/FAQ_plsql_out_param.html
  • 0 Comments
  • Filed under: 未分类
  • Windows 7 beta 7000使用有感

    前两天毫不犹豫安装上了Windows 7,虽然还是beta版,还有烦人的激活、非正版提示,虽然有不少人依然对Microsoft嗤之以鼻,不过我个人的观点是——基本上可以忘了Vista了。

    1、启动速度确实变快

    2、使用过Vista,能在Windows 7中感觉到微软在性能、易用性等细节上面的进步

    3、字体更加漂亮

    4、所有的硬件驱动自动搞定(包括打印机)

    5、常用软件98%都能正常使用(或启用Vista兼容模式运行),包括Oracle 11g

    6、安全似乎比Vista要严,进入交行网银时,密码输入控件必须将网站添加至信任站点才能正常工作,否则就算下载安装控件也不行。

    7、见下图,很贴心的功能,任何一个程序最近打开的文件都会列出来,而且可以将程序附到任务栏,作为之前的快速启动的替代

  • 2 Comments
  • Filed under: General
  • Time.now.to_s(:db)

    Time.now.strftime(”%Y-%m-%d %H:%M:%S”)

    Loading development environment (Rails 2.1.1)

    >> Time.now.to_s(:db)
    Time.now.to_s(:db)

    => “2008-11-27 14:45:54″

  • 0 Comments
  • Filed under: JS/Ajax, ROR
  • 升级Rails到2.1要注意的事情太多,不知道为何2.1禁用了URL SESSION的功能,cookie_only的设置不起作用了。

    查看action_controller/cgi_process.rb中的代码,已经没了根据cookie_only的设置的相关功能,如果需要打开这个功能,可以在config/initializers里面添加如下的patch:

    module ActionController
      class CgiRequest < AbstractRequest
        def session
          unless defined?(@session)
            if @session_options == false
              @session = Hash.new
            else
              stale_session_check! do
                session_key = session_options_with_string_keys['session_key']
                if cookie_only? && query_parameters[session_key]
                  raise SessionFixationAttempt
                end
                if !cookie_only? && @cgi.cookies[session_key].empty?
                  session_data = nil
                  if query_parameters[session_key]
                    session_data = [query_parameters[session_key]]
                  else
                    post_data = CGI.parse(body.read)
                    session_data = post_data[session_key]
                  end
                  @cgi.params[session_key] = session_data if session_data
                end
                case value = session_options_with_string_keys['new_session']
                when true
                  @session = new_session
                when false
                  begin
                    @session = CGI::Session.new(@cgi, session_options_with_string_keys)
                    # CGI::Session raises ArgumentError if 'new_session' == false
                    # and no session cookie or query param is present.
                  rescue ArgumentError
                    @session = Hash.new
                  end
                when nil
                  @session = CGI::Session.new(@cgi, session_options_with_string_keys)
                else
                  raise ArgumentError, "Invalid new_session option: #{value}"
                end
                @session['__valid_session']
              end
            end
          end
          @session
        end
      end
  • 0 Comments
  • Filed under: ROR
  • Rails 1.2升级至2.1(一)

    rails 从2.0起在控制器中废弃了observer方法,相关的错误信息:

    undefined method `observer’ for ApplicationController:Class (NoMethodError)

    解决的方法是将observer的设置信息移至enviroment.rb中:

    # Activate observers that should always be running
    config.active_record.observers = :cacher, :garbage_collector

  • 0 Comments
  • Filed under: ROR
  • Rails中连接Oracle的编码设置

    Oracle的字符编码有两种,一个是储存数据实际使用的编码,另外一个是客户端连接时的编码。当客户端连接时使用的编码与Oralce存储数据的编码不同时,Oracle会自动进行转换。因此即使Oracle数据存储的编码为UTF8,我们在命令行中使用sqlplus也能正常显示中文字符。

    Rails中生成页面缺省的编码都是UTF8,因此如果使用oci8连接Oracle就需要注意Rails连接Oracle时的编码设置,而不用去理会Oracle本身数据存储的编码。

    修改客户端连接时使用的编码通常的做法是修改注册表:
    HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1中的NLS_LANG值。
    缺省情况下中文系统会是GBK编码,例如:SIMPLIFIED CHINESE_CHINA.ZHS16GBK。
    如果将其修改为UTF8(SIMPLIFIED CHINESE_CHINA.AL32UTF8),在Rails中就应该能够正常存储,但是缺点是使用sqlplus时会出现乱码。

    另外一种方法是在环境变量中加入NLS_LANG项,设置为SIMPLIFIED CHINESE_CHINA.AL32UTF8,例如在命令行窗口中运行set NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8,运行Rails也没问题。这种设置不会影响到其他Oracle客户端。

    不过还有一个更好的办法,在Rails的enviroment.rb中添加一行:

    ENV['NLS_LANG'] = ‘SIMPLIFIED CHINESE_CHINA.AL32UTF8′
    其作用也是修改环境变量,不过其影响仅限于Rails中。另外要记得把这行代码放在enviroment.rb的最上面,不然不会生效!

  • 0 Comments
  • Filed under: Oracle, ROR
  • 谷歌浏览器Chrome

    Google发布浏览器了,众说纷纭。

    都说Google的目标是想做操作系统,其实做好浏览器的意义更大些。

    下载了试用了一下,界面简洁,速度还行,不过并不能感觉到有太多特别之处,可能因为是测试版吧。不知道未来会不会有插件的功能,习惯了鼠标手势操作和拖拽,没有这些功能的浏览器很难被我接受。试用了2分钟又换成火狐了。

    想想Google的网络服务使用的还是挺频繁的,几乎每天都要打开若干次GMail,Reader,但是桌面软件却很难留在电脑中,不知道大家是不是都这样。
    下载地址:http://www.google.com/chrome/

  • 0 Comments
  • Filed under: General
  • Alias Method for Class Method

    如何为类方法创建别名?方法是使用class << self。

    看下面的例子,需要覆盖TestClass.add方法

    class TestClass
    def self.add(aa)
    puts “add #{aa}”
    end
    end

    #开始打补丁
    class TestClass
    class << self
    alias_method :add1, :add
    end
    #覆盖TestClass.add方法
    def TestClass.add(aa)
    puts “cc”
    TestClass.add1(aa)
    end
    end

    TestClass.add “bb”

  • 0 Comments
  • Filed under: ROR
  • Ruby的另一杀手级应用——Shoes

    估计现在不少人还没有听说过Shoes,个人认为它将成为Ruby的又一新杀手级应用框架。
    Shoes的目标是一个轻量级的构建图形界面、图形和动画的跨平台应用框架。与传统的GUI框架不同,Shoes借鉴了不少Web特性,同时充分利用了Ruby构建DSL的优势,大大简化了构建图形界面或画图、制作动画的过程。非常类似与以前流行的LOGO语言,非常适合于作为计算机入门级语言,通过简单的语言构建丰富多彩的程序。
    目前Shoes推出了新的官方网站http://www.shoooes.net/,其最新的口号是“Colorful programs for Mac OS X, Linux and Windows”。最新的版本是0.r925,下载地址:http://www.shoooes.net/dist/shoes-0.r925.exe
    InfoQ曾经为Shoes做过专门的介绍:http://www.infoq.com/cn/news/2007/09/ruby-shoes

  • 0 Comments
  • Filed under: ROR