Переопределение строкового gsub - PullRequest
4 голосов
/ 25 февраля 2011

Я новичок в 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

Это моя отправная точка, и я ожидаю, что она будет работать так же, как и оригинальная строка. К сожалению, при таком переопределении некоторые существующие разрывы кода.

Как вы можете видеть в этом скрипте, я пытаюсь загрузить Sinatra и открыть страницу. Когда я делаю это и запрашиваю индекс, веб-сервер завершает работу со следующим выводом в консоли.

127.0.0.1 - - [25 / Feb / 2011 17:56:26] "GET / HTTP / 1.1" 200 13 0,0012 [2011-02-25 17:56:26] ОШИБКА NoMethodError: неопределенный метод `upcase 'для nil: NilClass /usr/local/ruby/lib/ruby/1.9.1/webrick/httpresponse.rb:172:in `блок (2 уровня) в 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 ' + плюс больше материала в след
[2011-02-25 17:56:26] ОШИБКА NoMethodError: неопределенный метод `[] 'для nil: NilClass /usr/local/ruby/lib/ruby/1.9.1/webrick/accesslog.rb:52:in "блок в формате" /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 Ответ

2 голосов
/ 25 февраля 2011

Реализация внутренней кодировки C в Ruby для gsub MRI делает некоторую магию для установки $&, $1 и т. Д. В вызывающем методе.Когда вы переопределяете gsub, они в конечном итоге устанавливаются в вашем переопределении, а не в вызывающей стороне вашего переопределения.

Я не знаю, как обойти это в МРТ.В Rubinius достаточно внутренних компонентов реализовано в Ruby и сделано доступным для пользовательского кода, что возможно .Это то, о чем Йегуда Кац упоминает в этом посте .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...