ruby – 重新定义String的gsub

我是
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: undefined method `upcase’ for nil:NilClass
/usr/local/ruby/lib/ruby/1.9.1/webrick/httpresponse.rb:172:in `block (2 levels) in send_header’
/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 `block in send_header’
+plus more stuff in the trace

[2011-02-25 17:56:26] ERROR NoMethodError: undefined method `[]’ for 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’
+more stuff in the trace

第一个例外(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有所不同?

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

我不知道在MRI中解决这个问题.在Rubinius中,足够的内部结构在Ruby中实现,并且可以访问用户级代码.这是耶胡达卡茨在this post年触及的事情.

点赞