Open tkshnwesper opened 2 years ago
What does it mean "when you run the test"? Can you show us the command?
What does it mean "when you run the test"? Can you show us the command?
Using crystal spec
This will probably be the answer: when you include something at the top level, it's included on every file, not just that file.
Even though I include only A::C
, does A::B
get automatically included too because they are both part of A
?
The spec runner creates a fictitious source file that require
s every spec file, so the two include
s effectively have the same scope, and the last one has precedence.
The spec runner creates a fictitious source file that
require
s every spec file, so the twoinclude
s effectively have the same scope, and the last one has precedence.
That explains the phenomenon well, thank you. I'll check the source code to see if there's an easy fix
I suppose it would be nice to have local includes per file which behave like private types in the top-level scope.
Maybe that should've been the behaviour for include
on the top-level in the first place. It seems to be what users would expect (I would, and the OP seems to assume that as well).
I think I get what you mean @straight-shoota , basically
include A::B
Z.new.foo(1)
include A::C
Z.new.foo("Hi")
should work in a single file, right?
No. I meant it should work as in your original example. When you include A::B
from b.cr
, it won't be included in other files such as c.cr
and vice versa.
I think I suggested private include in the past, there might be an issue for it.
I think I suggested private include in the past, there might be an issue for it.
Could it be this: https://github.com/crystal-lang/crystal/issues/4442
Wouldn't this also allow significan compiler performance boost (easier change detection)?
I wrote a small macro to localize includes: https://github.com/tkshnwesper/namespace
So now, I can run
require "namespace"
namespace A::B do
describe Z do
it "calls foo" do
Z.new.foo(1)
end
end
end
namespace A::C do
describe Z do
it "calls foo" do
Z.new.foo("Hello")
end
end
end
Bug Report
Repo to reproduce bug: https://github.com/tkshnwesper/potential_crystal_bug Run
crystal spec
Context
A
,A::B
andA::C
.b.cr
-A::B
has a methoddef foo(x : Int32)
c.cr
-A::C
has a methoddef foo(x : String)
A::B
(b_spec.cr
) only importsb.cr
A::C
(c_spec.cr
) only importsc.cr
b_spec.cr
-include
sA::B
c_spec.cr
-include
sA::C
When you run the test, you will get an error like
I'm not sure if it's a bug, or I am missing something. If we import only
c.cr
then it should use the methods defined inA::C
, no? Instead it looks atA::B
and pretendsA::C
does not exist.Crystal version: