Page 2 of 3
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 6:04 am
by idle
I see your point and the error message does supports what your saying
I guess my confusion is that I saw usemodule / unusemodule the same as a with / endwith block
just so we don't have to type in :: all the time
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 6:07 am
by BorisTheOld
I get the feeling that people want the "UseModule/UnUseModule" statements in the mistaken belief that the "module::item" notation is a burdensome feature that will increase coding time and effort.
In fact, it's the "UseModule/UnUseModule" feature that places a burden on the programmer, in that it opens the door to name conflicts and confusion about scope, the very problems that modules are supposed to solve. This is demonstrated in the above simple examples. Imagine the havoc that can be created in a large program with many "UseModule/UnUseModule" statements, misplaced "UnUseModule" statements, confusion about scope caused by duplicate names, and the gradual creation of spaghetti code.
With the "module::item" notation, none of that will happen. And because it only applies to public items, there will be no great burden on the programmer, since these items are small in number compared with the total amount of code. Also, the code will be easier to read and maintain, since there will be no confusion about what procedures and data items are being referenced.
Sometimes new features disimprove a language and have the potential for making life difficult. But since the "UseModule/UnUseModule" feature is probably here to stay, and in the interest of good programming practice, the workaround is to not use it.

Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 6:41 am
by Danilo
BorisTheOld wrote:But since the "UseModule/UnUseModule" feature is probably here to stay, and in the interest of good programming practice, the workaround is to not use it.

Agreed, but if there is no conflict, it could be useful sometimes to import the namespace. Good for lazy programmers...
Code: Select all
EnableExplicit
DeclareModule Danilo
; public functions, structures, constants here
Declare DaniloFunction1()
Declare DaniloFunction2()
EndDeclareModule
Module Danilo
private:
Global y.i ; variables always in private module part
Procedure Internal1()
Debug "internal:" + y
EndProcedure
public:
Procedure DaniloFunction1()
y = 1
Internal1()
EndProcedure
Procedure DaniloFunction2()
y = 2
Internal1()
EndProcedure
EndModule
UseModule Danilo ; use namespace Danilo
DaniloFunction1()
DaniloFunction2()
Maybe sometimes useful for codes without conflicts. Probably no conflicts if you use such long names.
The other way is to use always the full name without UseModule. So you can also use shorter function names that would conflict otherwise.
Code: Select all
EnableExplicit
DeclareModule File
Declare open(filename$)
EndDeclareModule
Module File
private:
public:
Procedure open(filenam$)
Debug #PB_Compiler_Module + "::"+ #PB_Compiler_Procedure
EndProcedure
EndModule
DeclareModule Window
Declare open(width, height)
EndDeclareModule
Module Window
private:
public:
Procedure open(width, height)
Debug #PB_Compiler_Module + "::"+ #PB_Compiler_Procedure
EndProcedure
EndModule
Define file, win1
file = File::open("1.txt") ; instead OpenFile()
win1 = Window::open(800,600) ; instead OpenWindow()
No conflicts, as long as you don't use UseModule. But no problem... we can choose our preferred style...

Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 11:10 am
by luis
Danilo wrote:
You can't import namespace x because namespace x contains a variable y. There is already a variable y in global namespace, that's why namespace x can't be imported.
An now I think we all agree on this.
(*)
Code: Select all
EnableExplicit
DeclareModule x
Define y = 33
EndDeclareModule
Module x
EndModule
Global y = 20
Debug y ; outputs 20
Procedure foo()
Protected y
Debug y ; outputs 0
EndProcedure
foo()
Danilo wrote:
Works as expected here. Protected y creates a new, local variable within the procedure.
In the code above you are not using the module in any way. Would be quite dramatic if it didn't work!
Code: Select all
EnableExplicit
DeclareModule x
Define y = 33
EndDeclareModule
Module x
EndModule
UseModule x
Debug y ; I understand this
Procedure foo()
Debug y ; but I don't understand why this should work, I don't see the logic behind this
EndProcedure
foo()
danilo wrote:
Yep, looks like a bug. "Debug y" in the procedure should only work if it is marked as Global in the module.
That was my original idea. But it's not a bug according to Fred, read this ->
http://www.purebasic.fr/english/viewtop ... 13#p423813
That's why I wrote this ->
http://www.purebasic.fr/english/viewtop ... 46#p424246
And last, about your code above
(*), if you change it this way:
Code: Select all
EnableExplicit
DeclareModule x
Define y = 33
EndDeclareModule
Module x
EndModule
UseModule x
Debug y ; I understand this
Procedure foo()
;Protected y
Debug y
EndProcedure
foo()
now we have lot of problems here
1) the fact the "debug y" inside the proc can access the module "define y".
You think it's a bug.
I thought it was a bug and I'm asking WHY it's this way (my post I linked above).
Fred says it's by design.
2) If you uncomment the "Protected y" the debug still print 33. So it's still accessing the module's var.
3) If you replaced the protected with "Protected y = 5" it prints 5. Again another different behavior. {EDIT: actually it just overwrite the module's var, I thought it was working correctly this way but it doesn't}
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 11:20 am
by Fred
2) is obviously a bug.
'UseModule' just makes all public members available in main program scope, and you can access them anywhere.
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 11:35 am
by luis
And that's it. Wrap your heads around it boys and remember the rule.
Using usemodule or accessing the declaremodule section contents using the full module path modulename::object make all the stuff declared in the interface of the module accessible everywhere (global), just ignore any scope attribute (define, global).
Those are valid only for the code in module/endmodule section.
Is this right ?
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 12:11 pm
by Fred
That's it

Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 2:31 pm
by Little John
Thanks for the lively discussion, which generated some more insight.
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 4:46 pm
by Danilo
luis wrote:And that's it. Wrap your heads around it boys and remember the rule.
Using usemodule or accessing the declaremodule section contents using the full module path modulename::object make all the stuff declared in the interface of the module accessible everywhere (global), just ignore any scope attribute (define, global).
Those are valid only for the code in module/endmodule section.
To explain it in code:
Code: Select all
DeclareModule MyModule
;
; Public module section
;
EnableExplicit ; for module namespace only!
Define Public_Define_var = 11
Global Public_Global_var = 22
;
; Access to DeclareModule stuff
;
Debug "inside DeclareModule MyModule"
Debug Public_Define_var ; access possible for module public "Define" variables
Debug Public_Global_var ; access possible for module public "Global" variables
EndDeclareModule
Module MyModule
;
; Private module section
;
Define Private_Define_var = 33
Global Private_Global_var = 44
;
; Access to DeclareModule and Module section
;
Debug "inside Module MyModule"
Debug Public_Define_var ; access possible for module public "Define" variables
Debug Public_Global_var ; access possible for module public "Global" variables
Debug Private_Define_var ; access possible for module private "Define" variables
Debug Private_Global_var ; access possible for module private "Global" variables
Debug "----"
Procedure Test()
;
; Access to GLOBAL DeclareModule and Module section only
;
Debug "inside MyModule::Test()"
; Debug Public_Define_var ; access NOT POSSIBLE for module public "Define" variables
Debug Public_Global_var ; access possible for module public "Global" variables
; Debug Private_Define_var ; access NOT POSSIBLE for module private "Define" variables
Debug Private_Global_var ; access possible for module private "Global" variables
Debug "----"
EndProcedure
Test()
EndModule
EnableExplicit ; for global namespace!
;
; Outside module, global namespace, in procedure
;
Procedure AccessMyModule()
;
; Access to DeclareModule (public) section
;
Debug "inside AccessMyModule()"
Debug MyModule::Public_Define_var ; access possible for module public "Define" variables
Debug MyModule::Public_Global_var ; access possible for module public "Global" variables
; Debug MyModule::Private_Define_var ; access NOT POSSIBLE for module private "Define" variables
; Debug MyModule::Private_Global_var ; access NOT POSSIBLE for module private "Global" variables
Debug "----"
EndProcedure
AccessMyModule()
;
; using UseModule, global namespace, in procedure
;
Procedure AccessMyModule_UseModule()
UseModule MyModule
;
; Access to DeclareModule (public) section
;
Debug "inside AccessMyModule_UseModule()"
Debug Public_Define_var ; access possible for module public "Define" variables
Debug Public_Global_var ; access possible for module public "Global" variables
; Debug Private_Define_var ; access NOT POSSIBLE for module private "Define" variables
; Debug Private_Global_var ; access NOT POSSIBLE for module private "Global" variables
Debug "----"
UnuseModule MyModule
EndProcedure
AccessMyModule_UseModule()
;
; using UseModule, global namespace, outside procedure
;
UseModule MyModule
;
; Access to DeclareModule (public) section
;
Debug "in global code space"
Debug Public_Define_var ; access possible for module public "Define" variables
Debug Public_Global_var ; access possible for module public "Global" variables
; Debug Private_Define_var ; access NOT POSSIBLE for module private "Define" variables
; Debug Private_Global_var ; access NOT POSSIBLE for module private "Global" variables
Debug "----"
UnuseModule MyModule
It is mostly OK. Just one thing is inconsistent in my opinion:
- I can access Public_Define_var from outside of the module,
also in outside procedures (that's the inconsistency).
- I can not access Public_Define_var inside module procedures itself.
- I can not access Private_Define_var inside module procedures itself.
A module should have access to everything in itself, in my opinion. A variable that is accessible from outside,
and not accessible in inside procedures does not make much sense, does it? Example for what it would be useful?
The inconsistency would at least go away if the same access rules would apply to Public_Define_var for inside and outside procedures (using UseModule),
means access to Public_Define_var with MyModule::Public_Define_var is always OK (full name used), but "UseModule MyModule : Debug Public_Define_var" in outside procedures
should be 'access denied'.
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 5:05 pm
by Little John
Danilo wrote:luis wrote:And that's it. Wrap your heads around it boys and remember the rule.
Using usemodule or accessing the declaremodule section contents using the full module path modulename::object make all the stuff declared in the interface of the module accessible everywhere (global), just ignore any scope attribute (define, global).
Those are valid only for the code in module/endmodule section.
To explain it in code:
It is already "explained in code" in the
first post of this thread.
That's why I wrote those snippets.
Danilo wrote:A module should have access to everything in itself, in my opinion.
Not to
everything in my opinion. IMHO Global, Shared etc. should apply (as it is currently the case).
Danilo wrote:A variable that is accessible from outside, and not accessible in inside procedures does not make much sense, does it?
That's strange for me, too. Therefore I think that a variable's scope (Global, Shared etc.) should not only apply inside the module, but also outside the module. However, Fred wants it to be as it currently is.
Re: Collection of test code snippets for modules
Posted: Sun Sep 08, 2013 5:13 pm
by Danilo
Little John wrote:It is already "explained in code" in the first post of this thread.
That's why I wrote those snippets.
I'm sorry, a thousand pardons!

Re: Collection of test code snippets for modules
Posted: Mon Sep 23, 2013 4:03 pm
by Little John
I've added another snippet (based on bug reports by idle and luis) to the small test code collection in the first post of this thread.
When testing all 4 code snippets with PB 5.20
final, everything works as expected.

Re: Collection of test code snippets for modules
Posted: Mon Sep 23, 2013 4:27 pm
by sec
Those test case are outdate too fast because Fred is too fast

Re: Collection of test code snippets for modules
Posted: Mon Sep 23, 2013 4:39 pm
by luis
sec wrote:Those test case are outdate too fast because Fred is too fast
I think the point of this test-suit is to more easily check against possible future regressions, not to check if a bug just marked as fixed is really fixed, for that the original code in the thread where it has been reported is more than enough.
Re: Collection of test code snippets for modules
Posted: Mon Sep 23, 2013 4:44 pm
by Little John
luis wrote:I think the point of this test-suit is to more easily check against possible future regressions
Exactly, thanks Luis.
And those tests can also help people who are new to PB (or new to PB's modules) to understand how modules and variable scope are exactly supposed to work.