我是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不同?
答案 0 :(得分:2)
MRI Ruby gsub
的内部C代码实现在调用方法中设置$&
,$1
等等有一定的魔力。当您重新定义gsub
时,它们最终会被重新定义,而不是重定义的调用者。
我不知道在MRI中解决这个问题。在Rubinius中,足够的内部结构在Ruby中实现,并且可以访问 的用户级代码。这是Yehuda Katz在this post中所涉及的内容。