Refer variables & closures defined in module from another file

Can someone please advise why I can refer to functions & macros from modules defined in another file but cannot refer to variables & closures from modules in another files. Though, I can include locally defined module from same file and can refer to variable & closure defined in it.

I am including in and executing

Crystal version 1.0.0 & LLVM 10.0.0

module Inc

  def incFunction : String
    "Include Function"

  macro incMacro
    "Include Macro"

  incClosure = ->{ "Include Closure" }

  incVar : String = "Include Var"


require "./inc"

module MainModule
  mainClosure = -> { "Main Closure" }
  mainVar : String = "Main Var"

include Inc
include MainModule

puts # => Main Closure
puts mainVar          # => Main Var

puts incFunction      # => Include Function
puts incMacro         # => Include Macro
puts  # => Error: undefined local variable or method 'incClosure' for top-level
puts incVar           # => Error: undefined local variable or method 'incVar' for top-level

Crystal has no global variables. Variables in the top-level scope are local variables scoped to the current file. Thus they’re inaccessible from other files.

Expressions directly inside a name space (i.e. not in a method or macro body) are part of the top-level scope of that file. The namespace does not create a nested scope. The variables defined in side MainModule are always accessible outside it, even without include MainModule.

In Ruby the variables are scoped (still inaccesible from outside). Ideally it should work like that in Crystal. Maybe for 2.0, but it’s a minor thing.


Thanks, I think this can be included in the documentation as it is mentioned here.

1 Like