Collection of test code snippets for modules
Re: Collection of test code snippets for modules
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
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
Windows 11, Manjaro, Raspberry Pi OS


-
BorisTheOld
- Enthusiast

- Posts: 542
- Joined: Tue Apr 24, 2012 5:08 pm
- Location: Ontario, Canada
Re: Collection of test code snippets for modules
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.
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.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
~ Spike Milligan
Re: Collection of test code snippets for modules
Agreed, but if there is no conflict, it could be useful sometimes to import the namespace. Good for lazy programmers...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.
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()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()Re: Collection of test code snippets for modules
An now I think we all agree on this.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.
(*)
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()In the code above you are not using the module in any way. Would be quite dramatic if it didn't work!Danilo wrote: Works as expected here. Protected y creates a new, local variable within the procedure.
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()That was my original idea. But it's not a bug according to Fred, read this -> http://www.purebasic.fr/english/viewtop ... 13#p423813danilo wrote: Yep, looks like a bug. "Debug y" in the procedure should only work if it is marked as Global in the module.
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()
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}
Last edited by luis on Sun Sep 08, 2013 3:57 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
Re: Collection of test code snippets for modules
2) is obviously a bug.
'UseModule' just makes all public members available in main program scope, and you can access them anywhere.
'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
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 ?
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 ?
"Have you tried turning it off and on again ?"
-
Little John
- Addict

- Posts: 4869
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Collection of test code snippets for modules
Thanks for the lively discussion, which generated some more insight.
Re: Collection of test code snippets for modules
To explain it in code: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.
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- 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'.
Last edited by Danilo on Sun Sep 08, 2013 5:06 pm, edited 1 time in total.
-
Little John
- Addict

- Posts: 4869
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Collection of test code snippets for modules
It is already "explained in code" in the first post of this thread.Danilo wrote:To explain it in code: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.
That's why I wrote those snippets.
Not to everything in my opinion. IMHO Global, Shared etc. should apply (as it is currently the case).Danilo wrote:A module should have access to everything in itself, in my opinion.
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.Danilo wrote:A variable that is accessible from outside, and not accessible in inside procedures does not make much sense, does it?
Re: Collection of test code snippets for modules
I'm sorry, a thousand pardons!Little John wrote:It is already "explained in code" in the first post of this thread.
That's why I wrote those snippets.
-
Little John
- Addict

- Posts: 4869
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Collection of test code snippets for modules
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.
When testing all 4 code snippets with PB 5.20 final, everything works as expected.
-
sec
- Enthusiast

- Posts: 792
- Joined: Sat Aug 09, 2003 3:13 am
- Location: 90-61-92 // EU or ASIA
- Contact:
Re: Collection of test code snippets for modules
Those test case are outdate too fast because Fred is too fast 
Re: Collection of test code snippets for modules
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.sec wrote:Those test case are outdate too fast because Fred is too fast
"Have you tried turning it off and on again ?"
-
Little John
- Addict

- Posts: 4869
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Collection of test code snippets for modules
Exactly, thanks Luis.luis wrote:I think the point of this test-suit is to more easily check against possible future regressions
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.

