Declaration of structures in the module

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Declaration of structures in the module

Post by BorisTheOld »

luis wrote: Keep in mind in that case the constants used to pilot the conditional compilation must be set by a third party, the user of the lib.
Would something like this work for you?

The user modifies an include file with values that are appropriate for his situation.

The following code is created by you, and is never modified by the user. The user just compiles it.

Code: Select all

;
;----------
;
;  mainline code
;
XincludeFile "Constants.pbi"
XIncludeFile "Macros.pbi"
XIncludeFile "Structures.pbi"
XincludeFile "ModifiedByUser.pbi"
.
. mainline code
.
End
;
;----------
;
Module M1
XincludeFile "Constants.pbi"
XIncludeFile "Macros.pbi"
XIncludeFile "Structures.pbi"
XincludeFile "ModifiedByUser.pbi"
.
. module 1 code
.
EndModule
;
;----------
;
Module M2
XincludeFile "Constants.pbi"
XIncludeFile "Macros.pbi"
XIncludeFile "Structures.pbi"
XincludeFile "ModifiedByUser.pbi"
.
. module 2 code
.
EndModule
;
;----------
;
Module M3
XincludeFile "Constants.pbi"
XIncludeFile "Macros.pbi"
XIncludeFile "Structures.pbi"
XincludeFile "ModifiedByUser.pbi"
.
. module 3 code
.
EndModule
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
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Declaration of structures in the module

Post by luis »

BorisTheOld wrote: Would something like this work for you?
The user modifies an include file with values that are appropriate for his situation.
No if I understand correctly what you are saying because that's asking the user to modify a file that is part of the library code (it's included by the library, so it's part of it).
Modifying an include that way would require for the user to do so every time he creates a new project based on that library, not very clean/practical.
My idea was for the user to define some constants in his main program just before including the main include of the library. Communicate his will to the lib code, but without altering it.
Without modules no problem, with modules now I got a good enough solution using the "Define" compiler command as I had hypothesized when was not yet available and how demonstrated by the example made by Helpy in that same thread (thank you).
Another solution would have been to access in a more simpler way the constants through the use of a nameless namespace, the famous "::constant_name" we have already discussed in other threads. I still would like it. I know it can go against the "black-box" concept of the module if abused. If not abused can solve situations like the above with zero headache, so I'm in favor of it.

Anyway, this thread is about another observation made by user_russian and this hasn't found a satisfactory solutions yet, I think.
"Have you tried turning it off and on again ?"
A little PureBasic review
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Declaration of structures in the module

Post by Little John »

luis wrote:Anyway, this thread is about another observation made by user_russian and this hasn't found a satisfactory solutions yet, I think.
Maybe something like this could be a solution (for PB being a one-pass compiler):

Code: Select all

DeclareModule x
   Protected Structure Private
      a.i
      b.i
      c.i
   EndStructure
   
   Structure Public
      var.Private
   EndStructure
   
   #test = SizeOf(Public)
EndDeclareModule


Module x
   
EndModule
"Protected" would mean here,that the structure "Private" is not visible outside of the module, although it is written inside the "DeclareModule" section. I know this is not elegant. However, now there is no violation of the black box module concept, and also e.g. SizeOf() can be used in the "DeclareModule" section, as shown in the example.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Declaration of structures in the module

Post by luis »

The point is DeclareModule/EndDeclareModule is the interface to the module.
By definition it should contain what of the module you decide to expose, and nothing else.
IMHO the only good place for the definition of a private structure is inside the body of the module.
Any possible solution should start from there. I don't see any (I didn't think about it a lot either yet) :)
"Have you tried turning it off and on again ?"
A little PureBasic review
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Declaration of structures in the module

Post by Little John »

luis wrote:The point is DeclareModule/EndDeclareModule is the interface to the module.
By definition it should contain what of the module you decide to expose, and nothing else.
IMHO the only good place for the definition of a private structure is inside the body of the module.
Any possible solution should start from there. I don't see any (I didn't think about it a lot either yet) :)
Luis, I agree to each single word of your message!
... especially to these words: "I don't see any" :-)
That's why I suggested an "ugly workaround".
Last edited by Little John on Wed Jul 03, 2013 3:44 pm, edited 1 time in total.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Declaration of structures in the module

Post by BorisTheOld »

luis wrote:No if I understand correctly what you are saying because that's asking the user to modify a file that is part of the library code (it's included by the library, so it's part of it).
Not quite.

The user would put his constants in his own file, but using a name that your code would recognize. Your code would remain untouched in its own Include file. So your customer isn't getting his fingers directly into your code.

It's not a lot different from the user hard coding the constants directly in his program, but it has the advantage of you being able to place them exactly where needed in your modules.

I'm curious, why does this have to be a compile-time feature, rather than have the user constants passed to a dynamic library at run-time?
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
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Declaration of structures in the module

Post by luis »

BorisTheOld wrote: The user would put his constants in his own file, but using a name that your code would recognize.
Do you mean an include file name my code would recognize ? If you mean that it's not what I want to do.
I want the user's include, or main program to communicate its will (or lack of, hence a default behavior) to my library module.
BorisTheOld wrote: I'm curious, why does this have to be a compile-time feature, rather than have the user constants passed to a dynamic library at run-time?
Because conditional compilation is a compile-time feature.

Both these aspects are explained in the original thread, using modules right now I don't see a better solution of what explained there.
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: Declaration of structures in the module

Post by helpy »

User_Russian wrote:Demivec, there is a main structure containing many nested structures (more than ten), and nested structures should not be accessible outside of the module.
At this point, we have to make public all the structures. Even if they would never used outside of the module. This violates the concept of a module as a black box.
You want a public structure with public and private elements.

Code: Select all

	Structure public
		pub_int.i
		pub_string.s
		Private priv_int.i
		Private priv_string.s
		Private priv_struct.StructureName
	EndStructure
This would be the only way to get a clean solution for your request.
Therefore you would need a new keyword in PureBasic.


The following would be the best solution with the current syntax:

Code: Select all

EnableExplicit

DeclareModule mod
  Structure public
    pub_int.i
    pub_string.s
  EndStructure
  
  Declare NewObject()
  Declare ChangeObject( *object.public )
  Declare FreeObject( *object.public )
EndDeclareModule

Module  mod
  Structure private Extends public
    priv_int.i
    priv_string.s
  EndStructure
  
  Procedure NewObject()
    Protected *object.private
    
    *object = AllocateMemory( SizeOf(private) )
    InitializeStructure( *object, private )
    
    With *object
      \pub_int = 100
      \pub_string = "Public String"
      
      \priv_int = 200
      \priv_string = "Private String"
    EndWith
    
    ProcedureReturn *object
  EndProcedure
  
  Procedure ChangeObject( *object.public )
    Protected *object_priv.private = *object
    
    With *object_priv
      \priv_int + 10
      \priv_string + " ==> changed"
      \pub_int + 10
      \pub_string + " ==> changed"
    EndWith
  EndProcedure
  
  Procedure FreeObject( *object.public )
    If Not *object
      FreeMemory( *object )
    EndIf
  EndProcedure
EndModule


Define *obj.mod::public

*obj = mod::NewObject()

With *obj  
  Debug \pub_int
  Debug \pub_string
  ; Debug \priv_int                  ; ==> ERROR: Structure field not found: priv_int
  ; Debug \priv_string               ; ==> ERROR: Structure field not found: priv_string
EndWith

Debug "----------"

mod::ChangeObject( *obj )

With *obj  
  Debug \pub_int
  Debug \pub_string
  ; Debug \priv_int                  ; ==> ERROR: Structure field not found: priv_int
  ; Debug \priv_string               ; ==> ERROR: Structure field not found: priv_string
EndWith

Debug "----------"

With *obj
  \pub_int + 1000
  \pub_string = "New public string"
EndWith

With *obj  
  Debug \pub_int
  Debug \pub_string
  ; Debug \priv_int                  ; ==> ERROR: Structure field not found: priv_int
  ; Debug \priv_string               ; ==> ERROR: Structure field not found: priv_string
EndWith

Debug "----------"

mod::ChangeObject( *obj )

With *obj  
  Debug \pub_int
  Debug \pub_string
  ; Debug \priv_int                  ; ==> ERROR: Structure field not found: priv_int
  ; Debug \priv_string               ; ==> ERROR: Structure field not found: priv_string
EndWith
cu,
guido
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Declaration of structures in the module

Post by luis »

User_Russian wrote:there is a main structure containing many nested structures (more than ten), and nested structures should not be accessible outside of the module.
helpy wrote: You want a public structure with public and private elements.

@user_russian

Is this what you want ? Because I thought you just wanted to solve the problem of the forward referencing needed by a structure defined in the interface (public) when part of its constituents are private structures.
user_russian wrote:At this point, we have to make public all the structures. Even if they would never used outside of the module.
The line above seems to indicate that.

And that's one thing.
What helpy says is something different and it's practically comparing a structure with a class, with private and public members. I don't think something like that is realistically going to pass.
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Declaration of structures in the module

Post by Demivec »

User_Russian wrote:Demivec, there is a main structure containing many nested structures (more than ten), and nested structures should not be accessible outside of the module.
At this point, we have to make public all the structures. Even if they would never used outside of the module. This violates the concept of a module as a black box.
@User_Russian: Thank you for your explanation (and also from luis's description of the same). I understand better now what the problem is that you started withs. It is not possible to declare a structure of structures if we don't declare the sub-structures first. If the sub-structures are private this is not possible with the current syntax. I suggested using pointers instead of a sub-structure but it doesn't really change this problem, it only replaces it with an incomplete alternative. I'm waiting to see if anyone has any better solutions. :)


My apologies for intermixing the thread topic with the unrelated thread that luis posted.
User_Russian
Addict
Addict
Posts: 1518
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Declaration of structures in the module

Post by User_Russian »

helpy, You are too complicate everything. All this can be done by standard means of PB, without working directly with the memory.
Especially as "Public" structure must contain some of the internal structure of the module are not accessible from outside, by name.
For example.

Code: Select all

DeclareModule X
  Structure Public
    Flags.l
    List Path.Private()
  EndStructure
EndDeclareModule

Module X

  Structure Private_2
    Name.s
    Date.l
  EndStructure

  Structure Private
    Dir.s
    List Files.Private_2()
  EndStructure
  
EndModule
This code will not work because of a single-pass compiler, so you need to add a new keyword Public, allowing declare a structure or other object (procedure, constant, array, etc.) available for export from the module.

Code: Select all

DeclareModule X

EndDeclareModule

Module X

  Structure Private_2
    Name.s
    Date.l
  EndStructure

  Structure Private
    Dir.s
    List Files.Private_2()
  EndStructure
  
  Public Structure Public
    Flags.l
    List Path.Private()
  EndStructure
  
EndModule
  
Test.x::Public

ForEach Test\Path()
  
Next
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: Declaration of structures in the module

Post by helpy »

Hi,

You want a public structure with en element, that should not be accessed from public.
Right?

An public structure with an structured element with a private structure!
Right?

Why would one want a public structure variable with an element which has a private structure.
All elements of an public structure variable are public! That is the syntax of PureBasic (recently).

For me it makes no sense to create a public structured variable with an element, which has an private structure.
This element would be public, but the type of this element would be unknown for the public ... how should that work?
User_Russian wrote:helpy, You are too complicate everything. All this can be done by standard means of PB, without working directly with the memory.
Especially as "Public" structure must contain some of the internal structure of the module are not accessible from outside, by name.
This is nothing else than hidden (private) elements in an public structure!

... maybe I am completly wrong and I do not understand you :?:
... maybe I need some light :idea: :idea:

cu,
guido
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Declaration of structures in the module

Post by freak »

You can hide the private parts in their own module:

Code: Select all

DeclareModule X_Private

  Structure Private_2
    Name.s
    Date.l
  EndStructure

  Structure Private
    Dir.s
    List Files.Private_2()
  EndStructure
  
EndDeclareModule

Module X_Private: EndModule


DeclareModule X
  Structure Public
    Flags.l
    List Path.X_Private::Private()
  EndStructure
EndDeclareModule

Module X
  UseModule X_Private

EndModule
Note however that the private elements can still be accessed from the outside. You have only hidden the structure declaration. You cannot hide parts of a structure from being accessible.

You can also use 'Extends' to truely shield the private parts as was already shown in this thread:

Code: Select all

DeclareModule X
  Structure Public
    Flags.l
  EndStructure
EndDeclareModule

Module X

  Structure Private_3
    Name.s
    Date.l
  EndStructure

  Structure Private_2
    Dir.s
    List Files.Private_3()
  EndStructure
 
  Structure Private Extends Public
    List Path.Private()
  EndStructure
 
EndModule
And no, we will not add a way to have a structure with half hidden and not hidden elements. That is just messy.

Btw, can you please put the whole "one-pass/two-pass" Discussion to rest? The rules of the PureBasic language are the way they are because we wanted them to be that way. Not because it was required by the compiler implementation. If we were to rewrite the compiler tomorrow, nothing would change regarding the syntax rules because they make sense the way they are.
quidquid Latine dictum sit altum videtur
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Declaration of structures in the module

Post by luis »

freak wrote:The rules of the PureBasic language are the way they are because we wanted them to be that way. Not because it was required by the compiler implementation.
Not talking about modules now.
Are you telling me you added the requirement of declaring procedures because you wanted to and not because the compiler is single pass ?
"Have you tried turning it off and on again ?"
A little PureBasic review
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Declaration of structures in the module

Post by freak »

The rule that things must be declared before they are used has existed since the beginning (even before the Declare keyword even existed). And it is a useful one too: While it forces you to write a little more it makes the code easier to understand by humans. If you read the code from the top down, you have all information you need to know the meaning of a line. Without this rule, you have to jump around in the code to find all the information you need, because the first line of the code may depend on the last line of the code for its declaration. I for one find this rule very useful.

And while it may have been an option to change this rule early on, it certainly isn't an option anymore. PureBasic has gained many advanced features since then that depend on this rule (macros, conditional compilation, etc) that changing it now would render these other features way more complex, with behavior that would be hard to follow by the programmer. Hard to understand compiler behavior leads to more coding errors. I prefer a little more typing in this case.
quidquid Latine dictum sit altum videtur
Post Reply