How how access a local variable from another module

For example:

# src/a.cr
require "crsfml"

module A
  window = SF::RenderWindow.new(SF::VideoMode.new(1080, 720), "My Window", SF::Style::Close)
  # ...

# src/b.cr
require "crsfml"
require "./a"
module B
  A.window.framerate_limit = 60
  # ...

I’m new to Crystal, I think what I need is something like static variable in Java

Local variables at the top level of the module cannot be accessed outside that top level, including methods under the module.
You can instead make it a class variable or a constant, and make a method that returns the value of it.

module A
  extend self
  @@test = "A"
  
  def test
    @@test
  end
end
 
p A.test # => "A"

By adding extend self, every method under the module will essentially behave like def self.method_name, making it a static method that can be accessed outside that module.
https://crystal-lang.org/reference/1.5/syntax_and_semantics/modules.html#extend-self

class_getter is a shorthand macro to define a class variable and a getter method that returns the value, as well as class_property for both getter and setter, and class_setter for setter only.
https://crystal-lang.org/api/1.5.0/Object.html#class_getter(*names,&block)-macro

module A
  class_getter test = "A"
  # is the same as writing:
  # @@test = "A"
  # def self.test
  #   @@test
  # end
end
 
p A.test # => "A"
1 Like

Thanks, it truly makes sense!

But now there is another problem:

Obviously, I have defined the lowp_mode boolean variable.
And before the class_getter macro was added, this problem didn’t exist.

I think that’s because class variables are always initialized before local variables.
If lowp_mode is not changing, you can change that to a constant. Otherwise, you might have to make that a class variable as well, but at that point, I think using module as a namespace is not suitable anymore.