Coding/Development Style Guide?

classic Classic list List threaded Threaded
21 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Coding/Development Style Guide?

4D Tech mailing list
Anybody out there have a style guide for development that they’ve written? I know a lot of people use shells that either they or others have written and that goes a long way toward supporting ease of maintenance of an app. Have you formalized guidelines on coding style, UI standards, naming conventions etc? I’m especially looking for examples that have worked well in team development.

Thanks for any input.

Tom Benedict
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
We have a family simple but effective set of rules for naming variables.
It's easy to follow and easy for anybody to know immediately what type of
variable it is:

Variable Naming Conventions

Begin each variable name with a character to specify what type it is:

·     String: s

·     Text: t

·     Boolean: y

·     Date: d

·     Time: h

·     Blob: b

·     Integer: i

·     Longint: o (because l looks too much like i)

·     Real: r

·     Object: j (because o has been in use for Longint)

If it’s a string then follow this with the string length.

If it’s an array, preface it with “a”

If it’s a 2-D array, preface it with “a2“

Follow this with a meaningful description of the variable.



Examples:

tErrorMessage (text variable for error messages)

atDocInfos – text array of document info

a2tFileInfos - 2-dimensional text array

On Fri, 14 Dec 2018 at 15:28, Tom Benedict via 4D_Tech <[hidden email]>
wrote:

> Anybody out there have a style guide for development that they’ve written?
> I know a lot of people use shells that either they or others have written
> and that goes a long way toward supporting ease of maintenance of an app.
> Have you formalized guidelines on coding style, UI standards, naming
> conventions etc? I’m especially looking for examples that have worked well
> in team development.
>
> Thanks for any input.
>
> Tom Benedict
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> Archive:  http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************



--
*************************************************
CatBase - Top Dog in Data Publishing
tel: +44 (0) 207 118 7889
w: http://www.catbase.com
skype: pat.bensky
*************************************************
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list

> Le 14 déc. 2018 à 16:48, Pat Bensky via 4D_Tech <[hidden email]> a écrit :
>
> We have a family simple but effective set of rules for naming variables.
> [...]

Hi,
we're using something similar for variables (except it's suffixes: myText_t, myDate_d, myTwoDimentionalArrayText_a2t, myObject_o, etc.)

Structure items
- tables uppercase
- fields camelCase
- primary keys "PK"
- foreign keys "FK_primaryKeyTableName"
- relations 1 to N "tableNname__F" (foreign)
- relations N to 1 "table1name__P" (primary)

For methods, often a prefix representing a group of the same "module"…

--
Arnaud de Montard



**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

RE: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Pat,

Love the j for object.  I had been trying to figure out what I wanted to do for that and hadn't yet.  Thanks for the idea.

Justin
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list

you asked for it   :)

here is my 'conventions' comment only method -
I place this in every project.

  //Project Method: _Conventions

  // • Created 2/16/10 by Chip -
  //• Updated 2/17/16 by Chip -
  //• Updated 3/24/16 by Chip -
  //• Updated 9/2/16 by Chip - added object naming, popup naming,
underscores, tab controls, listboxes

  //Underscores
  //Underscores '_' are used to sperarate words in a name,
field/variable/object/table/method, This is done to make
  //reading easier, and to make selection of the name simple. However,
in some cases a good name may be too long,
  //since 4D restricts some names to 32 characters, and so to make a
good name unserscores may be removed/not included.
  //However the CamelCase (as outlined below) is still respected, again
to make reading of the name(s) understandable.
  //    ex: the variable name : popup_Share_Restriction_Specific is too
long (more then 32 characters).
  //          the actual name used is : popup_ShareRestrictionSpecific

  //Object names                          `• Updated 9/2/16 by Chip -
  //Object names are the variable, or field name (or as close as
possible) + the prefix 'obj_'
  //obj_<variable/field name> - indicates that we are referencing the
item by it's objcet name

  //Variables
  //all process or interprocess vars are preceded by a type designator
  // I do not hold these conventions for local variables
  //this is in the form of :
  //    letter(s)_variablename
  //    letters for designator are always lower case

  //Variable names are always 1 word, with separate 'phrases' connected
by an underscore
  //the first letter of each 'phrase' is always capitalized.  
  //ex: al_My_Longint_Array

  //Variable type designators (trailing underscore NOT included here) :
  //a - array, this will always be followed by another type designator,
indicating the type of the array
  //b - button nearly always a long integer
  //blb - blob
  //cb - check box
  //cmb - combo box array, may NOT be the array on the form but a
secondary array of look up values (usually longint)
  //d - date
  //f - boolean (f=flag)
  //grf - graph
  //l - long integer
  //lb - list box
  //obj - is a prefix for OBJECTS, any object, which will be referenced
in code, or which has an object method
  //pic - picture
  //pop - popup/drop down menu                       `• Updated 9/2/16
by Chip -
  //ptr - pointer
  //r - real
  //rb - radio button
  //s - alphanumeric of some designated length -- may start including
string length but is not currently included (2-16-10)
  //        this designator is soon to vanish as string variable
definitions have been obsoleted (09-02-16)
  //t - time
  //tab - these are text arrays, and are tab controls objects
  //wa - web areas and related variables
  //x - text

  //Tab Controls
  //The titles - for the tab control are stored in internal Lists (as
of 09-02-16 -- Design -> Tool Box -> Lists).
  //Tab control - title lists are named:   Tab_<usage/module/form>
  //tab controls - are dimensioned as size 0 text arrays, a List to
Array command sizes and titles the tab control.
  //tab controls - usually have a project method to manage their
functioning. This method, if it exists, is named:
  //<module/form>_Manage_Tab

  //Listboxes
  //listboxes are complex objects. There are 3 modules of code to
manage these objects:
  //lstbox_Incld_<function>,  `lstbox_Output_<function>   and  
arylstbx_<function>
  //"Incld" - is used for listboxes displayed in an entry form.
  //"Output - is for listing forms,
  //'arylstbx' - is for all array based listboxes
  //Incld and Output listboxes - are expected to be (current) selection
based listboxes.
  //Output listboxes - are either NOT explicitly created (using a
default scheme based on {project form} 'List_box_Output'),
  //or are inherited from this same form.
  //Output listing forms - are based on this method call :
lstbox_Output_Open_Form, while inherited list forms
  //use the same command, but explicitly reference the inherited form's
name.
  //Ouput listboxes - are expected to be dragable.
  //Incld listboxes - are often droppable (from an output list box, or
desktop)
  //Listboxes - often have a project method to manage their
functioning, this method is named:
  //<module/form>_Manage_Listbox

  //Constants -
  //I use the 4D defined constants as needed, however, I have never
been comfortable with attempting to create my own constants.
  //To this end I use interprocess variables as constants.
  //These "constants" are defined in a variety of methods, all are
called from "strt_Variable_Assignments".
  //These methods are named in the following manner:
  //IPvars <area of database where contatns are used>

  //Method Names
  //Method names are always 1 word, with separate 'phrases' connected
by an underscore
  //the first character of each 'phrase' is capitalized
  //ex : modul_My_Method_Name

  //Method names attempt to group related methods together. The first
few (usually 5 or less) characters
  //indicate the 'module' or table which the method is intended to
operate on/with
  //module names are always lower case
  //ex : sampl_Do_Something_with_Samples

  //Method Modules
  //methods are grouped into 'modules' by the first few characters of
their name.
  //Most 'modules' have a comment only method, which may give a some
details about the specific module
  //what it does, where to expect its use. Those modules without an
information method are usually related to a specific table.
  //This comment only method is usually named "<module> Module_Info"  
(includes a space character)
  //the included space character insures that the module info method is
at the top (alphabetically) of the module method list
  //ex:  cls Module_Info

  //Method names starting with 'utl' are generic utility routines,
sometimes the 'utl' will be followed by a subgrouping designator
  //ex : utl_combo_Do_Something_with_Combobox

  //Form Methods
  //Forms generally will not have much code in their form method,
rather that code should reside in a project method.
  //The project method naming convention for these project methods is
as follows:
  //frmmth_ + <table/module/form_name> + _ + <Input/Output>

  //Tables
  //Table names are 1 or more 'phrases' connected by an underscore
  //the first character of each 'phrase' is capitalized
  //ex : My_Table

  //Many to Many - relational tables will normally have the word 'Link'
as part of the table name
  //Many to Many - relational tables will normally contain the name (or
an abreviation) of both Tables being linked
  //this is true only for tables which are pure linking tables.
  //ex : Table1_Table2_Link

  //in some instances the linking table maybe used for other functions,
in which case the table name will reflect that (those) use(s)

  //Fields
  //Field names are 1 or more 'phrases' connected by an underscore
  //the first character of each 'phrase' is capitalized
  //ex : My_Field_Name

  //Field names will generally reflect the use of the field  
  //there is no type designator applied to a field name
  //In all cases a field which ends in 'ID' will be the relational key
for the table, or a foreign key from an other table
  //All 'ID' fields are indexed Longint fields, and most will have at
least 1 relation

  //Fields that track last modification of a record are named :
  // Modified_Who

  //fields that track record creation information are named
  //  Created_Who - tracks who and when
  //  Created_Date - tracks only creation date

  //Journal Key/Primary Key                    • Updated 3/24/16 by
Chip -
  //begining with v13(?) a unique 'primary_key' value is needed for use
with Journalling
  //as it is suggested to use a UUID, and many tables use a numeric
relational key
  //a new field will be added to all new tables begining in v12, called
'Journal_Key'. It will be typed as text, and will be set as Invisible.
  //When added it is the intention to make this the LAST field of the
table.
  //this will be used as the UUID field in later 4D versions.
  //Eventually a 'Journal_Key' will be added to all tables.
  //As I touch tables (adding/deleting fields) I will add a Journal_key
field to the table

  //Other conventions

  //Relations and Fields
  //Fields with 2 or more relations will get a color. The same color is
applied to both the field name and the relations
  //this is intended to make it easier to follow which table(s) are
directly related

  //Menus
  //most actions started from a menu will start a new process (there
are a few exceptions)
  //all methods called directly from a menu start with the name 'menu_'

  //Method documentation
  //will at a minimum contain the name of the method (or object/form)
and a creation date and person
  //The creation date of a method reflects the date the method was
initiated, but may not contain updates to
  //the original code, until it is functioning as expected.
  //ex : a method created 2-10-10 may be worked on and modified until
2-16-10 at which time it is considered to be tested and functional
  //  although the 'functional date' is not recorded, and any
modifications during this the inital testing phase are usually not
recorded

  //if the method is subsequentally modified (say on 3-15-10) a
notation in header of the method will be made indicating when and who
made an update
  //usually a notation on the line(s) of code modified will also be
made.  This will depend on the amount of the modification.  In some
instances a rewrite
  //of the code is needed, and a note in header will be all to indicate
this.
  //Original code, when a rewrite, or method is deleted, will be copied
and saved (external to the database, usually text files with the date
of removal),
  // but will be removed from the system

  //• Updated 3/24/16 by Chip -
  //Method documentation - Important information
  //In some instances a method may have expectations of certain
conditions which may not be obvious,
  //code may be re-entrant, or recursive, or exepct to be called in
some specific order
  //To insure that these conditions are brought to the attention of the
developer, these types of conditions will be flagged
  //by a comment line/block which starts :
  //••• Note :

  //Method documentation - Parameters
  //parameters are indicated in the header comments of the method
  //parameters are indicated as to type, if it is optional, default
value if appropriate and what the parameter is being used for
  //valid values if there is a restricted set of values recognized
  //ex : $1 - Text (optional) - action to take, default value : clear
-- valid values : Clear, New, Add

  //parameters are always assigned to a local variable - hopefully
making the code easier to read/understand
  //parameters are always assigned to local variables - as the first
code run in a method, after type declarations.
  //The only exception is when a parameter is used (by its existence or
not) as a flag to do/not do an action, and is not directly referenced
  //ex : if (count parameters = 1)
  //          do something

  //Method documentation - Return values
  //if a method returns some value - it will be indicated by:
  //  RETURNS - <type of value> - description of returned value, with
possible definition of what a returned value means
  //This will always be the last comment line before the method
creation comment line

  //Method Documentation - ending a method
  //methods will end with one of the fallowing conventions:
  //  a blank comment line -- oldest
  //  a comment line with the text "end" -- old
  //  a comment line with the phrase "End <method name>"  -- current
(as of 2-18-10)

  //Methods - misc
  //type declarations for all variables are done immediately after the
end of the header comments.
  //parameters are always assigned to local variables - as the first
thing a method does, after type declarations
  //Return values are generally assigned a default value after
parameters, in the same section as locals are assigned from parameters
  //local variables are generally assigned a default value immediately
after parameters are assigned to local variables, and return values are
defaulted

  //If, case, repeat and other conditional and looping structure
commands are always separated by a blank line from any code above
  //this does not apply to comment(s) about the conditional, or loop
structure
  //ex :

  //The first condition is required to seperate the work from the else
condition (this is a comment line regarding the IF conditional to
follow)
  // IF (someting)
  //     run some code

  //      if (something else)
  //          run some additional code
  //      end if
  //end if

  //Case statement conditional tests are usually separated by a blank
line
  //ex:
  //case of
  //: (something)
  //     do something

  //: (something else)
  //     do something else
  //end case



  //Component Methods
  //method naming convention in components is similar to above method
naming convetions
  //with the exception that all EXPOSED methods are camel cased as
follows:
  //moduleAbrev_Module_Method_Description
  //methods which are NOT exposed, used internally, are camel cased as
follows :
  //moduleAbrev_module_Method_Description

  //Note :
  //Exposed - Module is capitalized first letter
  //Not exposed - module first letter is not capitalized


  //Component - Error handling
  // I will endevour to NOT open alert/confirm dialogs from components
for errors
  //All Exposed methods will include a mechanism for returning errors.
  //The errors will be (normally) text, including a description of the
error and a
  //method name in which the error occured.
  //ex:
  //"The pointer to text did not point to text -
My_Method_Requires_Text_Pointer"

  //Error returning will usually be either through :
  //Return of text (function) - empty string = no problem, or an error
message
  //Pointer to text - as a (normally optional last) parameter, in which
the error message (or nothing) will be returned
  //ex:
  //$Errors:=My_Component_Method(p1;p2) -- function return of error(s)
  //My_Component_Method(p1;p2;->$Errors) -- Error(s) returned in text
'$Errors'

  //It will be left up to the user of the component to manage any error
which occurs.


  //Component - parameters
  //Exposed methods should be heavily defensively coded, such that
passing in bad parameters
  //will get caught before an execution/runtime error occurs.
  //Parameter checking includes:
  //testing text values (where possible) for validity
  //testing numeric values for validity (range, positive, etc) where
possible
  //testing pointers for Nil
  //testing that pointers point to expected data types(s)


  //Components - Comments
  //the source code will be commented as per normal, and (header
comments)
  //maybe identical to the method's comment section.
  //Exposed methods will have the method Comment section populated

  //     parameters  
  //Exposed method's comments should include:
  //parameter(s) expounded as:
  //parameter number - type (optionality) - usage, valid values for the
parameter & default value if appropriate
  //ex: $3 - Text (optional) - add pad text to:  "L"- left, "R" -
right, 'B" - both (default is "L")

  //     Function return
  //If the component method is a function the return value will be
specified in a similar manner
  //to a parameter, except that return values will be labeled with
"RETURNS" (no quotes)
  //ex:  RETURNS - Text - source padded with selected characters to
defined length

  //     Description
  //Exposed methods will also contain a section describing the
action(s) of the method,
  //including, as needed, expounding of resticted values for the method
(from the method the above parameter example came from)
  //example:
  //Defaults are: space as a fill character($4), left fill($3)
source($1), do not truncate source($1)
  //if it is longer then specifed length($2)
  //
  //The source text ($1) is padded to specified length($2) by adding
the pad text to
  //specified side ($3-Left or Right), or by splitting the pad length
($3 - Both) and adding
  //an equal (plus or minus 1 character) amount of pad text to both
sides (left and right)

  //     Notes
  //Notes may include warnings, such as an array (passed via a pointer
parameter) will be cleared
  //before any new information is added. Or warnings about side effects
or limitations of the method.
  //Notes will typically be marked with the text :
  //"NOTE :" - no quotes


  //End _Conventions

On Fri, 14 Dec 2018 07:28:21 -0800, Tom Benedict via 4D_Tech wrote:

> Anybody out there have a style guide for development that they’ve
> written? I know a lot of people use shells that either they or others
> have written and that goes a long way toward supporting ease of
> maintenance of an app. Have you formalized guidelines on coding
> style, UI standards, naming conventions etc? I’m especially looking
> for examples that have worked well in team development.
>
> Thanks for any input.
>
> Tom Benedict
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> Archive:  http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
---------------
Gas is for washing parts
Alcohol is for drinkin'
Nitromethane is for racing
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
Thanks Chip. Very comprehensive! Do you have a similar guide for User Interface?

Tom

> On Dec 14, 2018, at 08:18, Chip Scheide <[hidden email]> wrote:
>
>
> you asked for it   :)
>
> here is my 'conventions' comment only method -
> I place this in every project.
>
>
> On Fri, 14 Dec 2018 07:28:21 -0800, Tom Benedict via 4D_Tech wrote:
>> Anybody out there have a style guide for development that they’ve
>> written?
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
no -
I probably should...
my UI is fairly simple in design:
- color coded entry areas
 -- Black - optional
 -- Red - non enterable (display only)
 -- Green - mandatory


I use the same record navigation buttons on all forms : Philadelphia
<button function> from 4D v2003?
these are arranged vertically on the left side of the page.


My list forms either directly calla Project form with a listbox, or use
the same project form as a parent where I need to add/remove
functionality. So these always look the same. The standard list form
has the following controls in the header (top) of the list form
- controls:
 - add button (if appropriate)
 - delete button  (if appropriate)
 - Print button (prints the related listing)
 - Search entry area (iTunes like) which searches the current selection
on a specific field (selectable via popup)
 - 'Quick Search' drop down menu containing pre defined searches which
are difficult for the user to construct (like searching for a field
which contains any value vs no value), searches across non related
tables, or searches across relations 2 or more level deep.
 - optional buttons specific to the table.


I generally use just a few Style-sheets - various font sizes as needed
Lucida-Grande [bold] (mac), Arial Baltic (windows) for buttons
Lucida-Grande (mac), Tahoma (windows) for entry areas and labels
  Printing - various font sizes as needed
Helvetica, Times/times New Roman, and Courier for printing


As of placement of entry areas on the screen, what ever order seems to
make the most sense for the purpose. I usually try to constrain the
width of entry form to the width of the listing form so no resizing is
needed when switching from list to entry form.


Tab controls/related record listbox are always on the bottom, with a
standard set of 'controls'
- controls:
 - add button (if appropriate)
 - delete button  (if appropriate)
 - Print button (prints the related listing)
 - Search entry area (iTunes like) which searches the current selection
on a specific field (selectable via popup)
 - optional buttons to open (separate process) other table list forms
for Drag-N-Drop (if appropriate)


I have not created a project form for inheritance for entry forms...
maybe I should. But I do have project form which contains all the base
components of my entry forms which I copy/paste as needed.
- header area
- navigation buttons
- a combobox & label
- a text entry area & label one each of differing color
- a couple of buttons for whatever need on the entry form
- cancel & accept buttons for dialogs
- invisible buttons for catching key strokes to close entry forms and
list form
  - command-period, esc, command-w, Alt-F4 etc

On Fri, 14 Dec 2018 08:28:09 -0800, Tom Benedict wrote:

> Thanks Chip. Very comprehensive! Do you have a similar guide for User
> Interface?
>
> Tom
>
>> On Dec 14, 2018, at 08:18, Chip Scheide <[hidden email]> wrote:
>>
>>
>> you asked for it   :)
>>
>> here is my 'conventions' comment only method -
>> I place this in every project.
>>
>>
>> On Fri, 14 Dec 2018 07:28:21 -0800, Tom Benedict via 4D_Tech wrote:
>>> Anybody out there have a style guide for development that they’ve
>>> written?
>
---------------
Gas is for washing parts
Alcohol is for drinkin'
Nitromethane is for racing
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Thanks Pat and Arnaud,

Seems it’s common to include datatype in variable/field names, whether it’s prefix or suffix is a matter of style. I find it very useful to know at a glance the type of an object, so I use a similar “modified Hungarian” notation too. For booleans I use the “is” prefix, which kinda breaks the rule, but reads so very logically.

A few years ago I stopped differentiating between integer and longInt, since 4D stopped. Likewise for string and text which 4D treats the same (except for when they are arrays).

I’m a fan of camelCase rather than underscores for word breaks, mainly for economy, but I like underscores after module prefixes in method names.

> On Dec 14, 2018, at 07:48, Pat Bensky via 4D_Tech <[hidden email]> wrote:
> We have a fairly simple but effective set of rules for naming variables.
>
> Begin each variable name with a character to specify what type it is:
>

> On Dec 14, 2018, at 08:11, Arnaud de Montard via 4D_Tech <[hidden email]> wrote:
> we're using something similar for variables (except it's suffixes: myText_t, myDate_d, myTwoDimentionalArrayText_a2t, myObject_o, etc.)

And I like Arnaud’s convention for tables and fields:
>
> Structure items
> - tables uppercase
> - fields camelCase
> - primary keys "PK"
> - foreign keys "FK_primaryKeyTableName"
> - relations 1 to N "tableNname__F" (foreign)
> - relations N to 1 "table1name__P" (primary)
>


I’d be interested in more comments about UI standards. I’ve often wished that 4D allowed the creation of custom form ‘templates’. I know that 4D has built-in form templates, button etc, but I’ve never found them appealing and the templates didn't support for dialog forms very well.

Also, Coding Style is a very big universe and many books are written on the subject. I got Steve Connoly's Code Complete many years ago and found it to be a great source of guidance.

Tom

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
Tom,
They do -
you can create a form and then inherit it.
Form properties -> Inherited form table --- only if the form is from a
table
Form properties -> Inherited form Name

This is what I do for list forms when I need to add functionality
different from my base list form.

Chip
On Fri, 14 Dec 2018 09:07:10 -0800, Tom Benedict via 4D_Tech wrote:
>
> I’d be interested in more comments about UI standards. I’ve often
> wished that 4D allowed the creation of custom form ‘templates’. I
> know that 4D has built-in form templates, button etc, but I’ve never
> found them appealing and the templates didn't support for dialog
> forms very well.
---------------
Gas is for washing parts
Alcohol is for drinkin'
Nitromethane is for racing
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
Hi Chip,

Thanks for pointing out that forms can be inherited. I’ve looked at Inherited Forms in the past and they struck me as having limited value since they cannot be modified on the child form. Record navigation and CRUD buttons are simple and can been generic, but custom features, function, workflow etc needs objects which can be modified in the child form.

I think what I really want is a “clone form” button in the form creation dialog which copies the objects from an existing form into the new form. I’ve always done that manually, which is OK, but it would be nice to have that ability integrated into 4D.

Tom

> On Dec 14, 2018, at 09:12, Chip Scheide <[hidden email]> wrote:
>
> Tom,
> They do -
> you can create a form and then inherit it.
> Form properties -> Inherited form table --- only if the form is from a
> table
> Form properties -> Inherited form Name
>
> This is what I do for list forms when I need to add functionality
> different from my base list form.
>
> Chip
> On Fri, 14 Dec 2018 09:07:10 -0800, Tom Benedict via 4D_Tech wrote:
>>
>> I’d be interested in more comments about UI standards. I’ve often
>> wished that 4D allowed the creation of custom form ‘templates’. I
>> know that 4D has built-in form templates, button etc, but I’ve never
>> found them appealing and the templates didn't support for dialog
>> forms very well.
>

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list

> Le 14 déc. 2018 à 18:35, Tom Benedict via 4D_Tech <[hidden email]> a écrit :
>
> Hi Chip,
>
> Thanks for pointing out that forms can be inherited.

I still have inherited, but in recent jobs I use subforms instead. They offer more solutions to design "shared parts" of UI.

--
Arnaud de Montard




**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Tom,

Back in the day (haven’t checked with recent versions of 4D), you could create/modify/save a template Form in the 4D Form creation tool.

Isn’t that what you are talking about doing here?

Thanks,
Walt Nelson (Seattle)
New stuff coming!
www.foundationshell.com
[hidden email]


> On Dec 14, 2018, at 11:35 AM, Tom Benedict via 4D_Tech <[hidden email]> wrote:
>
> I think what I really want is a “clone form” button in the form creation dialog which copies the objects from an existing form into the new form. I’ve always done that manually, which is OK, but it would be nice to have that ability integrated into 4D.

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Begin each variable name with a character to specify what type it is:
·     String: s
·     Text: t
·     Boolean: y

To add the Variable Type to the Variablename is a big help. I started many
years ago to prepend the Type. And I am using the "4D Pop Marco
Declaration" to automatically declare every variable. (I have a complete
Regex Setup for prepending the Type if someone need it).

But in the last days I am thinking if it would have been better to append
the Type: For example: $t_Name  vs.  $Name_t.
So if you are starting with a variable-name convention: Think about it
first.

And because of the Object-Tag names are case-sensitive, it makes sense to
have a convention for the Object-Tag names too. I use: every Name-Part
starts with a uppercase character and the rest is lowercase. Example Tags :
"Last_Changed" , "Simple_Tag".

My variable naming conventions :
C_LONGINT($l_WinRef)
C_OBJECT($o_parameter_3)
C_REAL($r_Amount)
C_TEXT($t_Customer_Code)
C_BOOLEAN($b_ok)
C_DATE($d_Budgets_End_Date)
C_OBJECT($o_Parameter)
C_POINTER($p_Table)
C_Blob($bl_Var)

ARRAY LONGINT($al_Budgets_Code;0)
ARRAY REAL($ar_Sum_of_Trades;0)


Bernd


PS: be careful with arrays and "4D Pop Marco Declaration": It moves the
declaration to the top of your Method. Use ARRAY
LONGINT($al_Budgets_Code;0x000)  to prevent it.

PPS: A Collegue uses the "4D Pop Marco Declaration" in a complete another
manner: He declares every variable by hand and then he uses the 4D Pop to
find every untyped or mistyped Variable. It works this way because he has
no "4D Pop Marco Declaration" setup for his convention.






Am Fr., 14. Dez. 2018 um 16:28 Uhr schrieb Tom Benedict via 4D_Tech <
[hidden email]>:

> Anybody out there have a style guide for development that they’ve written?
> I know a lot of people use shells that either they or others have written
> and that goes a long way toward supporting ease of maintenance of an app.
> Have you formalized guidelines on coding style, UI standards, naming
> conventions etc? I’m especially looking for examples that have worked well
> in team development.
>
> Thanks for any input.
>
> Tom Benedict
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> Archive:  http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
On Sun, Dec 16, 2018 at 10:15 PM B.Bippus via 4D_Tech <[hidden email]>
wrote:

> Begin each variable name with a character to specify what type it is:
> ·     String: s
> ·     Text: t
> ·     Boolean: y
>
> To add the Variable Type to the Variablename is a big help. I started many
> years ago to prepend the Type. And I am using the "4D Pop Marco
> Declaration" to automatically declare every variable. (I have a complete
> Regex Setup for prepending the Type if someone need it).
>
> But in the last days I am thinking if it would have been better to append
> the Type: For example: $t_Name  vs.  $Name_t.
> So if you are starting with a variable-name convention: Think about it
> first.
>
> And because of the Object-Tag names are case-sensitive, it makes sense to
> have a convention for the Object-Tag names too. I use: every Name-Part
> starts with a uppercase character and the rest is lowercase. Example Tags :
> "Last_Changed" , "Simple_Tag".
>
> My variable naming conventions :
> C_LONGINT($l_WinRef)
> C_OBJECT($o_parameter_3)
> C_REAL($r_Amount)
> C_TEXT($t_Customer_Code)
> C_BOOLEAN($b_ok)
> C_DATE($d_Budgets_End_Date)
> C_OBJECT($o_Parameter)
> C_POINTER($p_Table)
> C_Blob($bl_Var)
>
> ARRAY LONGINT($al_Budgets_Code;0)
> ARRAY REAL($ar_Sum_of_Trades;0)
>

I will offer a contrarian view: Some time ago, I was using the same
notation (Camel one, but that is detail) but now I decided against it.

I maintain several databases for a long time, so so I have a lot of
variables with 's' prefix, what is now text. This is not a big problem, I
can understand that 's' and 't' means the same, but it still disturb me a
bit. But with integer prefix i had a dilemma, as integer arrays still
exists and need to be used with integer fields, so I rather redeclared and
renamed all integer variables and arrays with 'l', but are still unsure
when I see 'ai' prefix in some old code - did I forgot to redeclare and
rename it, or is it still an integer (and should it be changed to longint?)

Second, as I often work with code written by different developer, mix of
various styles lead to not really well readable code. And I hate variable
names like $day_D (or, even better, $d_D) or $index_L etc. It provides no
information and makes the code ugly and unreadable. (Besides, does not 4D
now show variable type as cursor hoover above it?)

I now try to provide clear and readable variable names, without prefixes or
postfixes. This means I would have
C_LONGINT($winRef)
C_REAL($amount)
C_TEXT($customerCode)

I still use prefix when the type of variable is different from what the
name would suggest, but I prefer, when possible, names like $tablePtr;
$tableNo and $tableName to $p_table, $l_table and $t_table. I would still
use
C_BOOLEAN($bOK) but
C_LONGINT($OK)

I would still use
C_OBJECT($oParameter2)
but would try avoid such names.

Such names lead to readable code - like
For($index;1;$size)
  $sum:=$sum+$amount
...
works well with other notations, and are easier to write.

--

Peter Bozek
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
I agree with Peter. Object names need to convey what their purpose is, at
best, and be as unambiguous as possible at least. The size of the method
has a lot to do with how ambiguous a name might be. I have no qualms about
using $i as an index counter in a method where there is only one loop or
it's only a few lines long. It's really simple to rename variables if the
method starts to go long.

I've seen plenty of code with long var names, type appended, that are just
as difficult to read as code with abstruse names and no system. Personally
I think confusing naming schemes arise when the overall purpose of the code
is lost or poorly defined. A little time making sure we know what we are
doing might be more productive than typing long variables names.

Remember what they say, there are only 2 hard things in writing code:
naming things, clearing the cache and the off-by-one problem.

On Sun, Dec 16, 2018 at 2:08 PM Peter Bozek via 4D_Tech <
[hidden email]> wrote:

> On Sun, Dec 16, 2018 at 10:15 PM B.Bippus via 4D_Tech <
> [hidden email]>
> wrote:
>
> > Begin each variable name with a character to specify what type it is:
> > ·     String: s
> > ·     Text: t
> > ·     Boolean: y
> >
> > To add the Variable Type to the Variablename is a big help. I started
> many
> > years ago to prepend the Type. And I am using the "4D Pop Marco
> > Declaration" to automatically declare every variable. (I have a complete
> > Regex Setup for prepending the Type if someone need it).
> >
> > But in the last days I am thinking if it would have been better to append
> > the Type: For example: $t_Name  vs.  $Name_t.
> > So if you are starting with a variable-name convention: Think about it
> > first.
> >
> > And because of the Object-Tag names are case-sensitive, it makes sense to
> > have a convention for the Object-Tag names too. I use: every Name-Part
> > starts with a uppercase character and the rest is lowercase. Example
> Tags :
> > "Last_Changed" , "Simple_Tag".
> >
> > My variable naming conventions :
> > C_LONGINT($l_WinRef)
> > C_OBJECT($o_parameter_3)
> > C_REAL($r_Amount)
> > C_TEXT($t_Customer_Code)
> > C_BOOLEAN($b_ok)
> > C_DATE($d_Budgets_End_Date)
> > C_OBJECT($o_Parameter)
> > C_POINTER($p_Table)
> > C_Blob($bl_Var)
> >
> > ARRAY LONGINT($al_Budgets_Code;0)
> > ARRAY REAL($ar_Sum_of_Trades;0)
> >
>
> I will offer a contrarian view: Some time ago, I was using the same
> notation (Camel one, but that is detail) but now I decided against it.
>
> I maintain several databases for a long time, so so I have a lot of
> variables with 's' prefix, what is now text. This is not a big problem, I
> can understand that 's' and 't' means the same, but it still disturb me a
> bit. But with integer prefix i had a dilemma, as integer arrays still
> exists and need to be used with integer fields, so I rather redeclared and
> renamed all integer variables and arrays with 'l', but are still unsure
> when I see 'ai' prefix in some old code - did I forgot to redeclare and
> rename it, or is it still an integer (and should it be changed to longint?)
>
> Second, as I often work with code written by different developer, mix of
> various styles lead to not really well readable code. And I hate variable
> names like $day_D (or, even better, $d_D) or $index_L etc. It provides no
> information and makes the code ugly and unreadable. (Besides, does not 4D
> now show variable type as cursor hoover above it?)
>
> I now try to provide clear and readable variable names, without prefixes or
> postfixes. This means I would have
> C_LONGINT($winRef)
> C_REAL($amount)
> C_TEXT($customerCode)
>
> I still use prefix when the type of variable is different from what the
> name would suggest, but I prefer, when possible, names like $tablePtr;
> $tableNo and $tableName to $p_table, $l_table and $t_table. I would still
> use
> C_BOOLEAN($bOK) but
> C_LONGINT($OK)
>
> I would still use
> C_OBJECT($oParameter2)
> but would try avoid such names.
>
> Such names lead to readable code - like
> For($index;1;$size)
>   $sum:=$sum+$amount
> ...
> works well with other notations, and are easier to write.
>
> --
>
> Peter Bozek
>
--
Kirk Brooks
San Francisco, CA
=======================

*We go vote - they go home*
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
This says it all...
https://www.itworld.com/article/2823759/enterprise-software/124383-Arg-The-9-hardest-things-programmers-have-to-do.html#slide10 <https://www.martinfowler.com/bliki/TwoHardThings.html>

Dani Beaubien
Open Road Development

> On Dec 16, 2018, at 3:24 PM, Kirk Brooks via 4D_Tech <[hidden email]> wrote:
>
> I agree with Peter. Object names need to convey what their purpose is, at
> best, and be as unambiguous as possible at least. The size of the method
> has a lot to do with how ambiguous a name might be. I have no qualms about
> using $i as an index counter in a method where there is only one loop or
> it's only a few lines long. It's really simple to rename variables if the
> method starts to go long.
>
> I've seen plenty of code with long var names, type appended, that are just
> as difficult to read as code with abstruse names and no system. Personally
> I think confusing naming schemes arise when the overall purpose of the code
> is lost or poorly defined. A little time making sure we know what we are
> doing might be more productive than typing long variables names.
>
> Remember what they say, there are only 2 hard things in writing code:
> naming things, clearing the cache and the off-by-one problem.
>
> On Sun, Dec 16, 2018 at 2:08 PM Peter Bozek via 4D_Tech <
> [hidden email]> wrote:
>
>> On Sun, Dec 16, 2018 at 10:15 PM B.Bippus via 4D_Tech <
>> [hidden email]>
>> wrote:
>>
>>> Begin each variable name with a character to specify what type it is:
>>> ·     String: s
>>> ·     Text: t
>>> ·     Boolean: y
>>>
>>> To add the Variable Type to the Variablename is a big help. I started
>> many
>>> years ago to prepend the Type. And I am using the "4D Pop Marco
>>> Declaration" to automatically declare every variable. (I have a complete
>>> Regex Setup for prepending the Type if someone need it).
>>>
>>> But in the last days I am thinking if it would have been better to append
>>> the Type: For example: $t_Name  vs.  $Name_t.
>>> So if you are starting with a variable-name convention: Think about it
>>> first.
>>>
>>> And because of the Object-Tag names are case-sensitive, it makes sense to
>>> have a convention for the Object-Tag names too. I use: every Name-Part
>>> starts with a uppercase character and the rest is lowercase. Example
>> Tags :
>>> "Last_Changed" , "Simple_Tag".
>>>
>>> My variable naming conventions :
>>> C_LONGINT($l_WinRef)
>>> C_OBJECT($o_parameter_3)
>>> C_REAL($r_Amount)
>>> C_TEXT($t_Customer_Code)
>>> C_BOOLEAN($b_ok)
>>> C_DATE($d_Budgets_End_Date)
>>> C_OBJECT($o_Parameter)
>>> C_POINTER($p_Table)
>>> C_Blob($bl_Var)
>>>
>>> ARRAY LONGINT($al_Budgets_Code;0)
>>> ARRAY REAL($ar_Sum_of_Trades;0)
>>>
>>
>> I will offer a contrarian view: Some time ago, I was using the same
>> notation (Camel one, but that is detail) but now I decided against it.
>>
>> I maintain several databases for a long time, so so I have a lot of
>> variables with 's' prefix, what is now text. This is not a big problem, I
>> can understand that 's' and 't' means the same, but it still disturb me a
>> bit. But with integer prefix i had a dilemma, as integer arrays still
>> exists and need to be used with integer fields, so I rather redeclared and
>> renamed all integer variables and arrays with 'l', but are still unsure
>> when I see 'ai' prefix in some old code - did I forgot to redeclare and
>> rename it, or is it still an integer (and should it be changed to longint?)
>>
>> Second, as I often work with code written by different developer, mix of
>> various styles lead to not really well readable code. And I hate variable
>> names like $day_D (or, even better, $d_D) or $index_L etc. It provides no
>> information and makes the code ugly and unreadable. (Besides, does not 4D
>> now show variable type as cursor hoover above it?)
>>
>> I now try to provide clear and readable variable names, without prefixes or
>> postfixes. This means I would have
>> C_LONGINT($winRef)
>> C_REAL($amount)
>> C_TEXT($customerCode)
>>
>> I still use prefix when the type of variable is different from what the
>> name would suggest, but I prefer, when possible, names like $tablePtr;
>> $tableNo and $tableName to $p_table, $l_table and $t_table. I would still
>> use
>> C_BOOLEAN($bOK) but
>> C_LONGINT($OK)
>>
>> I would still use
>> C_OBJECT($oParameter2)
>> but would try avoid such names.
>>
>> Such names lead to readable code - like
>> For($index;1;$size)
>>  $sum:=$sum+$amount
>> ...
>> works well with other notations, and are easier to write.
>>
>> --
>>
>> Peter Bozek
>>
> --
> Kirk Brooks
> San Francisco, CA
> =======================
>
> *We go vote - they go home*
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> Archive:  http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list

> On Dec 16, 2018, at 14:24, Kirk Brooks via 4D_Tech <[hidden email]> wrote:
>
> Remember what they say, there are only 2 hard things in writing code:
> naming things, clearing the cache and the off-by-one problem.
>
That reminds me a signature I’ve seen thousands of times here. "There are three kinds of mathematicians, those who can count and those who can’t.

Tom Benedict
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
And one that I’ve seen frequently: there are 10 kinds of people in the world: those who understand binary and those who don’t.

Jeremy

> On 17 Dec 2018, at 03:51, Tom Benedict via 4D_Tech <[hidden email]> wrote:
>
>
>> On Dec 16, 2018, at 14:24, Kirk Brooks via 4D_Tech <[hidden email]> wrote:
>>
>> Remember what they say, there are only 2 hard things in writing code:
>> naming things, clearing the cache and the off-by-one problem.
>>
> That reminds me a signature I’ve seen thousands of times here. "There are three kinds of mathematicians, those who can count and those who can’t.


**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Tom:

We rewrote our shell for v16 from scratch. I also wanted to write complete documentation on using the shell too. That of course included naming convention for everything (even table names), includes lots of code that is very easy to add to code you are writing, and explanation of a lot of the code, and how to do things. The manual is just under 300 pages currently.

The naming convention (and the shell) is the result of many years of development with multiple developers and thousands of end users. It has been put through the wringer a few times over.

Sadly, I have not felt the need to complete the manual (I figure it is about 50% done).

Jody

Argus Productions Inc.



> On Dec 14, 2018, at 9:28 AM, Tom Benedict via 4D_Tech <[hidden email]> wrote:
>
> Anybody out there have a style guide for development that they’ve written? I know a lot of people use shells that either they or others have written and that goes a long way toward supporting ease of maintenance of an app. Have you formalized guidelines on coding style, UI standards, naming conventions etc? I’m especially looking for examples that have worked well in team development.
>
> Thanks for any input.
>
> Tom Benedict

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Coding/Development Style Guide?

4D Tech mailing list
Tom,

I use a naming convention and a set of methods that gets created for every module and form. I have used it with multiple programmers some where working on a server and some remotely. I would be glad to share with you if you like. Most of it is documented. It is based on using a four letter acronym for each module.

Feel free to contact me via email if you are interested.

Garri
________________________________
From: 4D_Tech <[hidden email]> on behalf of Jody Bevan via 4D_Tech <[hidden email]>
Sent: Tuesday, December 18, 2018 7:43 PM
To: 4D iNug Technical
Cc: Jody Bevan
Subject: Re: Coding/Development Style Guide?

Tom:

We rewrote our shell for v16 from scratch. I also wanted to write complete documentation on using the shell too. That of course included naming convention for everything (even table names), includes lots of code that is very easy to add to code you are writing, and explanation of a lot of the code, and how to do things. The manual is just under 300 pages currently.

The naming convention (and the shell) is the result of many years of development with multiple developers and thousands of end users. It has been put through the wringer a few times over.

Sadly, I have not felt the need to complete the manual (I figure it is about 50% done).

Jody

Argus Productions Inc.



> On Dec 14, 2018, at 9:28 AM, Tom Benedict via 4D_Tech <[hidden email]> wrote:
>
> Anybody out there have a style guide for development that they’ve written? I know a lot of people use shells that either they or others have written and that goes a long way toward supporting ease of maintenance of an app. Have you formalized guidelines on coding style, UI standards, naming conventions etc? I’m especially looking for examples that have worked well in team development.
>
> Thanks for any input.
>
> Tom Benedict

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
12