I discovered that if code is run within a Rails executor, refinements are not recognized. It doesn't seem to be because of blocks or procs, which was my only guess. Here's some demo code:
require './config/environment.rb'
module ExammpleRefinement
refine ::Kernel do
def say_hello
puts "hello"
end
end
end
using ExammpleRefinement
puts "alone"
say_hello
puts "block"
loop do
say_hello
break
end
puts "proc"
Proc.new{say_hello}.call
puts "rails executor"
::Rails.application.executor.wrap do
say_hello
end
run with ruby example.rb
(can't do it with rails runner
, because starting in rails 7 it wraps the entire script in an executor, so it ruins the experiment)
alone
hello
block
hello
proc
hello
rails executor
Traceback (most recent call last):
2: from example.rb:25:in `<main>'
1: from ....rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/execution_wrapper.rb:92:in `wrap'
scripts/example.rb:26:in `block in <main>': undefined local variable or method `say_hello' for main:Object (NameError)
CodePudding user response:
I wasn't able to reproduce the behaviour with the exact test file you provided (in my test it failed immediately after requiring config/environment
, regardless of executor wrapping), but I imagine I've tracked it to the same cause anyway:
During application initialization, likely due to use of EventedFileUpdateChecker, Kernel gets prepended by ForkTracker.
Presumably (and somewhat understandably), refinements doesn't like that.