method added via refinement not visible in rails controller

246 Views Asked by At

I have refined the Enumerable module in a Rails controller as follows, adding one method that, as far as I know, doesn't already exist in Rails or the standard library:

module OrderedGroupBy
  refine Enumerable do
    def ordered_group_by(&block)
      items = each
      groups = []
      prev = nil
      loop do
        begin
          i = items.next
          current = i.instance_eval(&block)
          groups << [] if current != prev
          prev = current
          groups.last << i
        rescue StopIteration
          break
        end
      end
      groups
    end
  end
end

using OrderedGroupBy

class TestController < ApplicationController
  def test
    numbers = ['one', 'three', 'seven', 'four', 'nine']
    @groups = numbers.ordered_group_by(&:length)
  end
end

Calling the controller action test results in a NoMethodError:

undefined method `ordered_group_by' for ["one", "three", "seven", "four", "nine"]:Array

To narrow down the problem, I created a standalone file with the same structure (without the Rails environment):

module OrderedGroupBy
  refine Enumerable do
    def ordered_group_by(&block)
      items = each
      groups = []
      prev = nil
      loop do
        begin
          i = items.next
          current = i.instance_eval(&block)
          groups << [] if current != prev
          prev = current
          groups.last << i
        rescue StopIteration
          break
        end
      end
      groups
    end
  end
end

using OrderedGroupBy

class TestController < Object
  def test
    numbers = ['one', 'three', 'seven', 'four', 'nine']
    @groups = numbers.ordered_group_by(&:length)
  end
end

TestController.new.test

In this case, calling the test method has the expected result:

# => [["one"], ["three", "seven"], ["four", "nine"]]

Also, if I define the ordered_group_by method directly on Enumerable, without using refine, I can successfully call the method.

Is there some reason why this would not work as a refinement in the context of Rails, or is there something else I'm missing?

Edit: I'm using rails 5.2.0, and this is an empty project, with only rails new _ and rails generate controller Test test having been run.

0

There are 0 best solutions below