Collection of test code snippets for modules

Everything else that doesn't fall into one of the other PB categories.
User avatar
idle
Always Here
Always Here
Posts: 6238
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Collection of test code snippets for modules

Post 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
Windows 11, Manjaro, Raspberry Pi OS
Image
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Collection of test code snippets for modules

Post 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. :)
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Collection of test code snippets for modules

Post 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... ;)
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Collection of test code snippets for modules

Post 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}
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 ?"
Fred
Administrator
Administrator
Posts: 18549
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Collection of test code snippets for modules

Post by Fred »

2) is obviously a bug.

'UseModule' just makes all public members available in main program scope, and you can access them anywhere.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Collection of test code snippets for modules

Post 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 ?
"Have you tried turning it off and on again ?"
Fred
Administrator
Administrator
Posts: 18549
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Collection of test code snippets for modules

Post by Fred »

That's it ;)
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Collection of test code snippets for modules

Post by Little John »

Thanks for the lively discussion, which generated some more insight.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Collection of test code snippets for modules

Post 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'.
Last edited by Danilo on Sun Sep 08, 2013 5:06 pm, edited 1 time in total.
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Collection of test code snippets for modules

Post 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.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Collection of test code snippets for modules

Post 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! :oops:
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Collection of test code snippets for modules

Post 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. :-)
sec
Enthusiast
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

Post by sec »

Those test case are outdate too fast because Fred is too fast :lol:
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Collection of test code snippets for modules

Post 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.
"Have you tried turning it off and on again ?"
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Collection of test code snippets for modules

Post 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.
Post Reply