Skip to content

Commit

Permalink
Showing 1 changed file with 16 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -881,6 +881,7 @@ public boolean isConstDefined(DynamicObject module, String fullName, boolean inh
public abstract static class ConstGetNode extends CoreMethodNode {

@Child private ReadConstantNode readConstantNode;
@Child private KernelNodes.RequireNode requireNode;

public ConstGetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -927,12 +928,17 @@ public Object getConstantScoped(DynamicObject module, DynamicObject fullName, bo

@TruffleBoundary
private Object getConstantNoInherit(DynamicObject module, String name, Node currentNode) {
final RubyConstant constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);
RubyConstant constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);

if (constant == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorUninitializedConstant(module, name, this));
} else {
if (constant.isAutoload()) {
loadAutoloadedConstant(module, name, constant);
constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);
}

return constant.getValue();
}
}
@@ -955,6 +961,15 @@ boolean isScoped(DynamicObject name) {
return name.toString().contains("::");
}

private void loadAutoloadedConstant(DynamicObject module, String name, RubyConstant constant) {
if (requireNode == null) {
CompilerDirectives.transferToInterpreter();
requireNode = insert(KernelNodesFactory.RequireNodeFactory.create(getContext(), getSourceSection(), null));
}

requireNode.require((DynamicObject) constant.getValue());
}

}

@CoreMethod(names = "const_missing", required = 1)

2 comments on commit ba286b5

@nirvdrum
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eregon I had to pull some code in from DefineOrGetModuleNode here. We probably should work out what's common and what's not. For the time being, I've only handled the "no inherit" case.

I also was looking at adding specs, but it's not clear if they should be in the const_get or the autoload specs. It's sort of an integration test. Thoughts?

@eregon
Copy link
Member

@eregon eregon commented on ba286b5 Jan 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put specs in const_get since autoload just declares the autoload, but const_get actually triggers it.

Please sign in to comment.