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.