Bug #1072: Ripper#filename
http://redmine.ruby-lang.org/issues/show/1072

起票者: Kazuhiro NISHIYAMA
ステータス: Open, 優先度: Normal
カテゴリ: ext
Reproducible Version: trunk, ruby -v: ruby 1.9.1p5000 (2009-01-30 trunk 21885) [i686-linux]

Ripper::Filter#filenameが定義されているのにRipper#filenameが定義されていないため、NoMethodErrorになります。

% cat ~/check_regexp_n.rb
#!/usr/bin/ruby

require 'ripper/filter'

class CheckRegexpN < Ripper::Filter
  def on_regexp_end(token, data)
    if /n/ =~ token
      puts "#{filename}:#{lineno}:#{column}:#{token}"
    end
  end
end

ARGV.each do |path|
  open(path, "rb") do |f|
    parser = CheckRegexpN.new(f, path)
    p [parser.filename, parser.lineno, parser.column]
    parser.parse
    p [parser.filename, parser.lineno, parser.column]
  end
end
% ruby-trunk -vd ~/check_regexp_n.rb lib/minitest/spec.rb
ruby 1.9.1p5000 (2009-01-30 trunk 21885) [i686-linux]
Exception `NoMethodError' at .../1.9.1/ripper/filter.rb:27 - undefined method `filename' for #<Ripper::Lexer:0x8170bbc>
.../1.9.1/ripper/filter.rb:27:in `filename': undefined method `filename' for #<Ripper::Lexer:0x8170bbc> (NoMethodError)
        from .../check_regexp_n.rb:16:in `block (2 levels) in <main>'
        from .../check_regexp_n.rb:14:in `open'
        from .../check_regexp_n.rb:14:in `block in <main>'
        from .../check_regexp_n.rb:13:in `each'
        from .../check_regexp_n.rb:13:in `<main>'
%

ripper_linenoをまねして以下のようにripper_filenameを定義してみたのですが、
    if (NIL_P(parser->parsing_thread)) return Qnil;
の行があるとnilしか返ってこなかったのでコメントアウトしています。

Index: parse.y
===================================================================
--- parse.y	(リビジョン 21885)
+++ parse.y	(作業コピー)
@@ -10239,6 +10239,25 @@
 
 /*
  *  call-seq:
+ *    ripper#filename   -> String
+ *
+ *  Return current parsing filename.
+ */
+static VALUE
+ripper_filename(VALUE self)
+{
+    struct parser_params *parser;
+
+    Data_Get_Struct(self, struct parser_params, parser);
+    if (!ripper_initialized_p(parser)) {
+        rb_raise(rb_eArgError, "method called for uninitialized object");
+    }
+/*    if (NIL_P(parser->parsing_thread)) return Qnil; */
+    return parser->parser_ruby_sourcefile_string;
+}
+
+/*
+ *  call-seq:
  *    ripper#lineno   -> Integer
  *
  *  Return line number of current parsing line.
@@ -10288,6 +10307,7 @@
     rb_define_method(Ripper, "initialize", ripper_initialize, -1);
     rb_define_method(Ripper, "parse", ripper_parse, 0);
     rb_define_method(Ripper, "column", ripper_column, 0);
+    rb_define_method(Ripper, "filename", ripper_filename, 0);
     rb_define_method(Ripper, "lineno", ripper_lineno, 0);
     rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
     rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);


----------------------------------------
http://redmine.ruby-lang.org