Some precautions on using modules

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
Modules (or their properties/attributes/variables etc) seem to be not capable of recognizing things below it when setting up constants (at least that's where I encounter problems).

This is important for some things like XS Menu for example which uses a module for setting up it's menu list (directly declaring a Scene name inside the module). Because of this behavior, all custom scenes that you will call via XS menu must be above it else it will return an error because it will try to find the scene inside the module. It's actually because of this script that I remembered that modules seem to work that way.

Code:
#this returns an error when the custom scene script was below xailmodule somemoduleMENU_BLAH = [BLAH,Scene_Custom_Scene]end#But it now works when the Custom Scene script was placed above XAIL
I'm not sure of any other script out there that is afflicted with that problem but I think it's for the benefit of everyone to remember this behavior of modules.
 
Last edited by a moderator:

Mouser

Veteran
Veteran
Joined
Aug 19, 2012
Messages
1,245
Reaction score
264
First Language
English
Primarily Uses
That has nothing to do with modules, but sequential code execution.

X is not defined when it is referred to in line 3 (Height = ...). The interpreter has no idea what to do with it. It could be a string, an array, anything.  Put those three lines in any script and you'll get the same error.

Edit: Ruby being as extremely OO as it is, what X is, is an Object (or BaseObject now in Ruby 1.9). The arithmetic operators aren't defined for the BaseObject or Object class.

Incidentally, sequential code execution is one of the three fundamental control flow structures required to solve algorithms (loops and conditional branches being the other two).
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
I just said modules since that's where I encountered it... and also because it was actually mainly about XAIL's script


where this didn't work


module somemodule


SOME_VARIABLE = MY_CUSTOM_SCENE


end


when the custom scene script was below XAIL


But yeah I was thinking probably it's because it was initializing constants so positioning is important...


PS: Anyone who knows a lot more is free to clarify things up. :)
 
Last edited by a moderator:

Mouser

Veteran
Veteran
Joined
Aug 19, 2012
Messages
1,245
Reaction score
264
First Language
English
Primarily Uses
Ok, I see what you're getting at now - the example you gave used variables but I think what you're really talking about are forward function (method) calls. I'd have to look it up to see how Ruby deals with those at runtime. In C, you put the headers ahead of where they need to be and you can define the functions later on (necessary if two functions call each other). Ruby doesn't have those, so it's got to have some way of checking - or the circular function thing wouldn't work, which I know it does.

Part of the advantage of an interpreted language is the ability to do things like that.

It's also part of the disadvantage of an interpreted language, as well...
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
I do think the problem is with the fact that it was still on initializing phase during the constant setting part so it can only look for things that are already initialized... so it might indeed be because of the sequence. :)


So I think it's just that it's more likely to happen in modules used for settings. Especially on the case presented where we directly set a Class into a constant variable inside a module. Because otherwise (like the original example) it is pretty obvious that it won't work.


PS: I was actually amazed when RGSS3 was able to do calls to functions/methods below the call coz I'm used to wc3 where it's also not allowed.
 
Last edited by a moderator:

Evgenij

Veteran
Veteran
Joined
Aug 28, 2013
Messages
349
Reaction score
100
First Language
German
Primarily Uses
N/A
I dont know if its ideal, but you could just predefine all used classes before the module:

class Scene_Test < Scene_Base; end; module Test  abc = Scene_TestendThen the position of the Script which contains the class doesnt matter anymore.

One of the problems is, that you need to know the superclass
 
 

Kaelan

Veteran
Veteran
Joined
May 14, 2012
Messages
797
Reaction score
537
First Language
Portuguese
Primarily Uses
RMMV
That's what I do for some of my code. I just forward declare all classes that other constants depend on at the top of the file, then write the definitions that use them and the classes themselves in the order that logically makes sense later in the file.
 

Solistra

Veteran
Veteran
Joined
Aug 15, 2012
Messages
593
Reaction score
247
Primarily Uses
Your original question has already been answered (kind of, the answer is actually quite simple), so I'd just like to say this: the XS Menu using constants is totally unnecessary. Symbols could be used just as easily, and a constant can be generated from them using Object.const_get(symbol). Likewise, you could use anything that can be converted cleanly into a symbol and just cast the object to a symbol in the call to const_get.

Honestly, using constants to build a menu list is just silly. And if the developer was concerned about nested constants (like Module::Scene), that's easily taken care of:

Code:
class String  def to_const    split('::').reduce(Object) { |obj, const| obj.const_get(const) }  endendmodule Example  CONSTANT = :valueend'Example::CONSTANT'.to_const # => :value
 

BadMinotaur

You can do it!
Veteran
Joined
Mar 13, 2012
Messages
260
Reaction score
115
First Language
English
Primarily Uses
RMVXA
From what I understand (and I'm probably wrong, since Modules still confuse me), Modules act like singleton classes -- whereas a class won't throw an error until you try to instance it, Modules are essentially instances of the Module class itself. So when you're defining a Module, it's actually running the variables, etc. that you put outside of any method definitions as it sees it. Whereas classes don't do that, because class initialization doesn't happen 'til you instance the class.

So essentially, from what I can recall,

I do think the problem is with the fact that it was still on initializing phase during the constant setting part so it can only look for things that are already initialized...
This is 100% correct.
 

BadMinotaur

You can do it!
Veteran
Joined
Mar 13, 2012
Messages
260
Reaction score
115
First Language
English
Primarily Uses
RMVXA
Why would that be?
 

BadMinotaur

You can do it!
Veteran
Joined
Mar 13, 2012
Messages
260
Reaction score
115
First Language
English
Primarily Uses
RMVXA
I was more interested in the structural reason behind it. I know about == and === and all of the weird things those can do, but maybe it's just late but I can't really wrap my head around why Zeriab's situation works.

If Module.is_a?(Class), then that means that Module is an instance of Class or is an instance of a class that has Class as one of its superclasses. Whereas if Class.is_a?(Module), then that means that Class is an instance of Module or is an instance of a class that has Module as one of its superclasses. This doesn't make sense to me, how would you even declare that?

Unless Class and Module redefine #is_a?, but why would they do that?
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
I was more interested in the structural reason behind it. I know about == and === and all of the weird things those can do, but maybe it's just late but I can't really wrap my head around why Zeriab's situation works.

If Module.is_a?(Class), then that means that Module is an instance of Class or is an instance of a class that has Class as one of its superclasses. Whereas if Class.is_a?(Module), then that means that Class is an instance of Module or is an instance of a class that has Module as one of its superclasses. This doesn't make sense to me, how would you even declare that?

Unless Class and Module redefine #is_a?, but why would they do that?
The way I understand it is all classes in Ruby are instances of the class Class, so the classes you make are all instances of class Class and all of the built-in classes are instances of class Class. So the reason why Module.is_a?(Class) is true is because Module itself is an instance of class Class. The class Class also has a superclass of Module, so Class.is_a?(Module) is also true because Class is an instance of class Class which has a superclass of Module. 

So, yea... It's all a little circular.
 

BadMinotaur

You can do it!
Veteran
Joined
Mar 13, 2012
Messages
260
Reaction score
115
First Language
English
Primarily Uses
RMVXA
That's pretty interesting. It still seems weird to me since I thought Ruby was more internally "proper" than that -- it's so OO, I didn't think stuff like Module being a superclass of Class while being an instance of Class happened.

I actually did learn that if a class is mixed in with a module, then #is_a? will return true for that mixed-in module. So if Class somehow has Module mixed-in with it, then Class.is_a?(Module) will return true, even if Class isn't an actual descendent of Module. But if Module isn't an actual module... hm. You know I have the Ruby book, I should just look this up at some point.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:
To whom ever person or persons who re-did the DS/DS+ asset packs for MV (as in, they are all 48x48, and not just x2 the pixel scale) .... THANK-YOU!!!!!!!!! XwwwwX

Forum statistics

Threads
105,849
Messages
1,016,975
Members
137,563
Latest member
cexojow
Top