Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7
    • Fix Version/s: JRuby 1.7.0.pre1
    • Component/s: Parser, Ruby 1.9.2
    • Labels:
      None
    • Number of attachments :
      0

      Description

      I noticed this while working on some custom library code to implement '!~'

      Patch to add this to RubySpec, which currently fails in JRuby 1.6.7: https://github.com/jruby/rubyspec/pull/2

      irb session showing the failure:

      % JRUBY_OPTS=--1.9 irb                      
      >> JRUBY_VERSION + " " +  JRUBY_REVISION
      => "1.6.7 3e82bc8"
      >> class Foo; def !~(val); return val; end; end
      => nil
      >> Foo.new.send(:"!~", /bar/)
      => /bar/
      >> Foo.new !~ /bar/
      => true
      

      In the above example, 'Foo.new !~ /bar/' should have returned /bar/, not true.

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        Appears to be a parsing problem. It's parsing as in 1.8, as !(a =~ b):

        system ~/projects/jruby $ ast -e 'a =~ b'
        AST:
        RootNode 0
          NewlineNode 0
            CallOneArgNode:=~ 0
              VCallNode:a 0
              ArrayNode 0
                VCallNode:b 0
        
        
        system ~/projects/jruby $ ast -e 'a !~ b'
        AST:
        RootNode 0
          NewlineNode 0
            NotNode 0
              CallOneArgNode:=~ 0
                VCallNode:a 0
                ArrayNode 0
                  VCallNode:b 0
        
        
        system ~/projects/jruby $ jruby --1.8 -S ast -e 'a !~ b'
        AST:
        RootNode 0
          NewlineNode 0
            NotNode 0
              CallOneArgNode:=~ 0
                VCallNode:a 0
                ArrayNode 0
                  VCallNode:b 0
        

        It should parse as a call to :!~.

        Show
        Charles Oliver Nutter added a comment - Appears to be a parsing problem. It's parsing as in 1.8, as !(a =~ b): system ~/projects/jruby $ ast -e 'a =~ b' AST: RootNode 0 NewlineNode 0 CallOneArgNode:=~ 0 VCallNode:a 0 ArrayNode 0 VCallNode:b 0 system ~/projects/jruby $ ast -e 'a !~ b' AST: RootNode 0 NewlineNode 0 NotNode 0 CallOneArgNode:=~ 0 VCallNode:a 0 ArrayNode 0 VCallNode:b 0 system ~/projects/jruby $ jruby --1.8 -S ast -e 'a !~ b' AST: RootNode 0 NewlineNode 0 NotNode 0 CallOneArgNode:=~ 0 VCallNode:a 0 ArrayNode 0 VCallNode:b 0 It should parse as a call to :!~.
        Hide
        Hiro Asari added a comment -

        I think you meant obj !~ thing.

        Show
        Hiro Asari added a comment - I think you meant obj !~ thing .
        Hide
        Charles Oliver Nutter added a comment -

        Here's a hacky parser fix, but I'm not sure whether it's exactly correct. MRI may have short-circuited logic for !~ when one side or the other is a String or Regexp, and this would not reflect that short-circuiting.

        diff --git a/src/org/jruby/parser/Ruby19Parser.y b/src/org/jruby/parser/Ruby19Parser.y
        index 0830745..0562e8c 100644
        --- a/src/org/jruby/parser/Ruby19Parser.y
        +++ b/src/org/jruby/parser/Ruby19Parser.y
        @@ -899,7 +899,7 @@ arg             : lhs '=' arg {
                           */
                         }
                         | arg tNMATCH arg {
        -                    $$ = new NotNode(support.getPosition($1), support.getMatchNode($1, $3));
        +                    $$ = support.getOperatorCallNode($1, "!~", $3, lexer.getPosition());
                         }
                         | tBANG arg {
                             $$ = support.getOperatorCallNode(support.getConditionNode($2), "!");
        
        Show
        Charles Oliver Nutter added a comment - Here's a hacky parser fix, but I'm not sure whether it's exactly correct. MRI may have short-circuited logic for !~ when one side or the other is a String or Regexp, and this would not reflect that short-circuiting. diff --git a/src/org/jruby/parser/Ruby19Parser.y b/src/org/jruby/parser/Ruby19Parser.y index 0830745..0562e8c 100644 --- a/src/org/jruby/parser/Ruby19Parser.y +++ b/src/org/jruby/parser/Ruby19Parser.y @@ -899,7 +899,7 @@ arg : lhs '=' arg { */ } | arg tNMATCH arg { - $$ = new NotNode(support.getPosition($1), support.getMatchNode($1, $3)); + $$ = support.getOperatorCallNode($1, "!~", $3, lexer.getPosition()); } | tBANG arg { $$ = support.getOperatorCallNode(support.getConditionNode($2), "!");
        Hide
        Charles Oliver Nutter added a comment -

        I incorporated a modified version of your spec, as well as sending a PR upstream to rubyspec/rubyspec.

        Show
        Charles Oliver Nutter added a comment - I incorporated a modified version of your spec, as well as sending a PR upstream to rubyspec/rubyspec.
        Hide
        Hiro Asari added a comment -

        Seems to me that Charlie's "hacky" fix is exactly what is happening in MRI: https://github.com/ruby/ruby/blob/7af3e9f08b6f277b7f96d7ed2a0115d1452d98cc/parse.y#L2340

        We should commit that, I'd think.

        Show
        Hiro Asari added a comment - Seems to me that Charlie's "hacky" fix is exactly what is happening in MRI: https://github.com/ruby/ruby/blob/7af3e9f08b6f277b7f96d7ed2a0115d1452d98cc/parse.y#L2340 We should commit that, I'd think.
        Hide
        Hiro Asari added a comment -

        I pushed the fixed to the main branch: 5e78f58.

        Show
        Hiro Asari added a comment - I pushed the fixed to the main branch: 5e78f58.

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Jordan Sissel
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: