重新定义String的gsub

时间:2011-02-25 15:04:38

标签: ruby sinatra

我是ruby的新手,我遇到了第一个棘手的问题。我试图重新定义String的一些方法,以便附加一些功能。有问题的方法似乎是gsub。 (编辑)让我粘贴我的main.rb来展示这个错误。

require 'rubygems' if RUBY_VERSION < "1.9"
require 'sinatra'

class String
    alias_method :old_gsub, :gsub
    def gsub (*params, &block )
        old_gsub *params, &block
    end
end

get '/' do
  s="Hello world! "
end

这是我的出发点,我希望它能像原始String一样工作。不幸的是,通过这种重新定义,一些现有的代码会中断。

正如您在此脚本中看到的,我尝试加载Sinatra并提供页面。当我执行此操作并请求索引时,Web服务器将失败并在控制台中显示以下输出。

127.0.0.1 - - [25 / Feb / 2011 17:56:26]“GET / HTTP / 1.1”200 13 0.0012 [2011-02-25 17:56:26] ERROR NoMethodError:nil的未定义方法`upcase':NilClass         /usr/local/ruby/lib/ruby/1.9.1/webrick/httpresponse.rb:172:在send_header'中阻止(2级)         /data/Dropbox/Ruby/RubyTrack/lib/main.rb:227:in`gsub'         /data/Dropbox/Ruby/RubyTrack/lib/main.rb:227:in`gsub'         /usr/local/ruby/lib/ruby/1.9.1/webrick/httpresponse.rb:172:in在send_header中的块 +在追踪中加上更多东西
[2011-02-25 17:56:26] ERROR NoMethodError:未定义的方法`[]'为nil:NilClass         /usr/local/ruby/lib/ruby/1.9.1/webrick/accesslog.rb:52:in“block in format”         /data/Dropbox/Ruby/RubyTrack/lib/main.rb:227:in`gsub'         /data/Dropbox/Ruby/RubyTrack/lib/main.rb:227:in`gsub'         /usr/local/ruby/lib/ruby/1.9.1/webrick/accesslog.rb:50:in“format” 跟踪中的更多东西

第一个例外(httpresponse.rb:172)在行

tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase }

,第二个错误是由(accesslog.rb:50)

的结果引起的
format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/)

从上面可以看出,我使用的是Ruby 1.9.1(尽管ruby -v给了我1.9.2p0)。我在Ubuntu 10.04上。确实,我的Ruby配置可能有问题,在Ubuntu中安装它有点乱。

所以,总结一下,为什么我对gsub的重新定义与原来的gsub不同?

1 个答案:

答案 0 :(得分:2)

MRI Ruby gsub的内部C代码实现在调用方法中设置$&$1等等有一定的魔力。当您重新定义gsub时,它们最终会被重新定义,而不是重定义的调用者。

我不知道在MRI中解决这个问题。在Rubinius中,足够的内部结构在Ruby中实现,并且可以访问 的用户级代码。这是Yehuda Katz在this post中所涉及的内容。