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.