2011-02-25 6 views
4

나는 루비를 처음 접했고, 나는 처음으로 까다로운 문제에 직면했다. 나는 그들 주위에 몇 가지 기능을 첨부하기 위해 문자열의 일부 메서드를 재정의하려고합니다. 문제가있는 방법은 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를로드하고 페이지를 제공하려고합니다. 이 작업을 수행하고 색인을 요청하면 웹 서버가 실패하고 콘솔의 다음 출력이 표시됩니다.

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)

(accesslog.rb 50)의 결과에 의해 발생되는 라인

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

두 번째 오류에

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

위에서 루비 1.9.1을 사용하고 있다고 나와 있습니다 (루비 -v는 1.9.2p0를 제공하지만). 나는 우분투 10.04에있다. 루비의 설정에 문제가있을 수 있다는 점은 사실입니다. 우분투에 설치하는 것은 다소 지저분한 일이었습니다.

요약하면 gsub에 대한 나의 재정의 정의가 원래 gsub와 다른 이유는 무엇입니까?

+1

왜 String에 새로운 메소드를 추가하지 않는가? gsub 재정의를 다른 이름으로 부르기 만하면됩니다. – david4dev

+0

Ruby의이 기능이 내가 언어를 사용하는 이유입니다. 필자는 특정 보안 속성을 시행하기 위해 프로그램의 동작을 투명하게 편집하는 것에 관한 연구를 수행하는 겸손한 Phd입니다. 따라서 기존 기능에 대해 다른 정의를 제공해야합니다. – Yiannis

+1

몇 가지 오류를 게시 할 수 있습니까? – DanSingerman

답변

2

MRI Ruby의 내부 C 코드 구현 gsub은 호출 방법에서 $&, $1 등을 설정하는 마술을합니다. gsub을 다시 정의하면 재정의 호출자가 아니라 재정의에서 설정이 끝납니다.

나는 이것을 MRI에서 해결할 방법을 모른다. Rubinius에서는 내부 구조가 Ruby로 구현되어 사용자 수준 코드에 액세스 할 수 있으므로 입니다. 이것은 Yehuda Katz가 this post에서 접촉 한 것입니다.