Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-require causes the problems with inheritance #6462

Closed
untied opened this issue Jul 28, 2018 · 6 comments
Closed

Cross-require causes the problems with inheritance #6462

untied opened this issue Jul 28, 2018 · 6 comments

Comments

@untied
Copy link

untied commented Jul 28, 2018

Simple cross-require code with two abstract classes causes the inheritance problem.

Project structure:

/src/main.cr
/src/modules/module.cr
/src/modules/network/network_module.cr

Module and NetworkModule are both abstract classes. NetworkModule extends Module. The Module class also has the static method that loads NetworkModule's subclasses into its hash.

Here is the code:

# FILE: src/main.cr

require "./modules/module"

module MyApp
  puts "Cross-require inheritance bug demo"

  MyApp::Modules::Module.load
end
# FILE: src/modules/module.cr

require "./network/network_module"

module MyApp::Modules
  alias NetworkModule = MyApp::Modules::NetworkModule

  abstract class Module
    # a hash of network modules
    @@network = {} of Int32 => NetworkModule

    # here network modules should be loaded
    def self.load
      puts "Network modules have been loaded..."
    end
  end
end
# FILE: src/modules/network/network_module.cr

require "../module"

module MyApp::Modules::Network
  include MyApp::Modules
  # alias Module = MyApp::Modules::Module # this approach also causes the bug

  abstract class NetworkModule < Module
    # something about networking ...
  end
end

The compiler reports this error:

in src/modules/network/network_module.cr:8: undefined constant Module (did you mean 'Modules')

  abstract class NetworkModule < Module
                                 ^~~~~~
@asterite
Copy link
Member

module requires network_module, before defining Module. This is working as expected, it's not a bug. Define Module before requiring the other file.

@untied
Copy link
Author

untied commented Jul 29, 2018

No, it's definitely a bug!
Since Crystal is the compiling language the order of definitions has no matter.
Besides I cannot require NetworkModule after the Module's definition 'cause Module class should contain the static hash of NetworkModules.
And besides number 2: the similar code in Java or D-lang compiles without any troubles.

@asterite
Copy link
Member

Order of definition does matter in Crystal. This is not D nor Java.

Im Crystal you can define a class, define another class, then reopen the first one and add whatever you need to it. This is sometimes called forward declaration in other languages. You sometimes need it in Crystal (you need it here).

@asterite
Copy link
Member

Sorry I don't provide code, I'm on a cellphone.

@RX14
Copy link
Contributor

RX14 commented Jul 30, 2018

Should we close this? Could/should we make this possible for at least non-macro defined classes.

@untied
Copy link
Author

untied commented Aug 4, 2018

Yes, the double definition of the parent class has solved the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants