-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JRuby 9.1.17.0 fails when using 'contracts' gem #5155
Comments
So I've reduced the issue to a self contained script: module InheritHook
def inherited(subclass)
puts "InhertHook#inherited called for #{subclass}"
subclass.base_or_eigenclass_instance.set_eigenclass_owner
end
end
class Base
def initialize(klass)
puts "#{self.class}#initialize called for #{klass}"
@klass = klass
puts "Returning #{self}"
end
def set_eigenclass_owner
puts "Base#set_eigenclass_owner called on #{self}"
@klass.singleton_class.base_or_eigenclass_instance.owner_class = 'something'
end
end
class EigenClass < Base
attr_writer :owner_class
end
module Engine
def self.apply(target, klass = Base)
puts "Engine.apply called on #{target}, #{klass}"
return if target.respond_to?(:base_or_eigenclass_instance)
apply_to_eigenclass(target)
target.instance_eval do
define_method(:base_or_eigenclass_instance) do
@base_or_eigenclass_instance ||= klass.new(self)
end
end
end
private
def self.apply_to_eigenclass(target)
puts "Engine.apply_to_eigenclass called on #{target}"
return if (target <= Object.singleton_class)
singleton_class = target.singleton_class
singleton_class.extend(InheritHook)
apply(singleton_class, EigenClass)
apply(singleton_class)
end
end
Object.extend(InheritHook)
Engine.apply(Object)
class C end Executing with Ruby 2.5 yields e.g.
JRuby 9.1.17.0 on the other hand returns
So there are obvious differences, but I haven't yet narrowed it down further and thought I'd share my work before someone else went through the same kind of trouble Moving the |
Somewhat smaller variation that no longer raises, but whose output still shows difference between mri and jruby module InheritHook
def inherited(subclass)
puts "InhertHook#inherited(#{subclass})"
subclass.base_or_eigenclass_instance
end
end
class Base
def initialize(klass)
puts "#{self.class}#initialize(#{klass})"
@klass = klass
end
end
class EigenClass < Base
end
module Engine
def self.apply(target, klass = Base)
puts "Engine.apply(#{target}, #{klass})"
if target.respond_to?(:base_or_eigenclass_instance)
puts "Early return because already applied"
return
end
apply_to_eigenclass(target)
target.instance_eval do
define_method(:base_or_eigenclass_instance) do
@base_or_eigenclass_instance ||= klass.new(self)
end
end
end
private
def self.apply_to_eigenclass(target)
puts "Engine.apply_to_eigenclass(#{target})"
return if (target <= Object.singleton_class)
singleton_class = target.singleton_class
singleton_class.extend(InheritHook)
apply(singleton_class, EigenClass)
apply(singleton_class)
end
end
Object.extend(InheritHook)
Engine.apply(Object)
class C end Note there are two separate, but probably related, parts:
|
A further self contained reduction for the first bullet of the previous comment. Almost all changes now change the result and makes the output for mri and jruby equal module ExtendedModule end
klass = Object.singleton_class
klass.extend(ExtendedModule)
if !klass.respond_to?(:dynamically_defined_method)
puts "Defining dynamically_defined_method"
klass.instance_eval do
define_method(:dynamically_defined_method) {}
end
end
puts klass.respond_to?(:dynamically_defined_method) MRI
JRuby
Especially note that the InheritHook doesn't do anything, but is still necessary. The same goes for the One of the few things that (fortunately) doesn't make a difference is using |
@Confusion Thanks for the extra footwork on this! I am not sure if we can get it done for 9.2, but your reproductions will help us get it fixed soon. |
Hmm, at a glance I'd guess that the define_method call is not executing against the proper context, so the defined method goes somewhere else. |
Confirmed broken on master. |
Code
Expected Behavior
The script executes successfully with exit code 0
Actual Behavior
The contracts gem performs some interesting Ruby voodoo :)
Environment
jruby 9.1.17.0 (2.3.3) 2018-04-20 d8b1ff9 OpenJDK 64-Bit Server VM 25.162-b12 on 1.8.0_162-8u162-b12-0ubuntu0.16.04.2-b12 [linux-x86_64]
Linux photon 4.4.0-119-generic #143-Ubuntu SMP Mon Apr 2 16:08:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Only gem: contracts 0.16.0
JRuby 9.1.8.0 shows the same behavior.
The text was updated successfully, but these errors were encountered: