2011-02-25 63 views
4

我是新来的红宝石,我刚刚遇到我的第一个棘手的问题。我试图重新定义String的一些方法,以便在它们周围附加一些功能。有问题的方法似乎是gsub。 (编辑)让我粘贴我的main.rb展示这个错误。重新定义字符串的gsub

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不同?

+1

为什么不直接向String中添加新的方法?只需将您的gsub重新定义为不同的名称即可。 – david4dev 2011-02-25 15:46:19

+0

Ruby的这个特性是我尝试这种语言的原因。我是一个谦虚的博士做一些研究,透明地编辑程序的行为来执行某些安全属性。因此,我需要为现有功能提供不同的定义。 – Yiannis 2011-02-25 15:54:18

+1

你可以发布一些错误代码吗? – DanSingerman 2011-02-25 16:43:54

回答

2

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

我不知道在MRI中解决这个问题。在Rubinius中,足够的内部是在Ruby中实现的,并且可以通过用户级代码访问它,因为它可能是。这是耶胡达卡茨在this post接触到的东西。