Closed djboardman closed 5 years ago
This is gonna be hard to fix.
@meh is it related to $scope not having the right information?
It's deeper than that. The Object
constants are always looked up, because when you're inside a class definition you want to be able to access any constants that go up to Object
.
But when getting a constant directly with a different base, you don't want anything but the class/module scopes constants to come up. And you want both to use #const_missing
.
Constant handling probably has to be rewritten from scratch, it would help if rubyspec/language/constants_spec
could run, but they crash even before running, just to tell you how broken constants are right now.
It also would help if Ruby constant semantics weren't absolutely insane. There are some corners of Ruby that are semantical nightmares, but only people who want to implement Ruby will know.
@meh yea, thats too bad. Its funny that I haven't run into this issue until now. Guess its just an issue if your shadowing a higher up class. Well, maybe for now we'll just pick a different class name. :-) Let me know if I can help on this. (Sounds like a big project though)
@ryanstout it only happens if you forget to declare an inner constant, i.e. when you forget to require a file, and there's a constant with the same name up.
@djboardman @meh @ryanstout - the fix from #1110 appears to have fixed the 2nd case but it does not fix the 1st.
Work's on latest release 🎉
opal:master ⤑ pbpaste | ruby -v - ~/C/opal
ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-darwin18]
Traceback (most recent call last):
-:10:in `<main>': uninitialized constant MyModule::MyClass (NameError)
opal:master ⤑ pbpaste | opal -v - ~/C/opal
Opal v1.0.0
/private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:4679
throw exception;
^
MyClass: uninitialized constant MyModule::MyClass
at Function.$$const_missing (/private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:3066:52)
at const_missing (/private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:224:32)
at Opal.const_get_qualified (/private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:271:38)
at /private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:23478:7
at Object.<anonymous> (/private/var/folders/w0/yjfqr9n94ld7ft4j3hlz_fsm0000gn/T/opal-nodejs-runner-20190731-21526-15ekt5o:23489:3)
at Module._compile (internal/modules/cjs/loader.js:759:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
at Module.load (internal/modules/cjs/loader.js:628:32)
at Function.Module._load (internal/modules/cjs/loader.js:555:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:822:10)
opal:master ⤑
There seem to be a couple of differences in how Opal handles classes scoped by modules vs how native Ruby handles them.
The first one is when the class does not exist inside the module but is initialized as if it did:
When this is run in Ruby:
When the same thing is run in Opal:
The second example is when there is when the class does exist in the module:
When run in Ruby then
#class
gives the fully scoped name:While Opal responds to
#class
with only the name of the class without the module:The first example in particular is causing an issue for me because if the module with the scoped class is accidentally not required then Opal silently creates an unscoped class.