Sheerpower®
A Guide to the Sheerpower Language


Previous Contents Index


Appendix M
Sheerpower and Program Segmentation

It is a proven fact that the maintenance of existing software accounts for 80% of software costs. Therefore, the key to writing efficient code is to keep routines short, simple and easy to maintain.

Coding Standards and Writing Professional Code

See Appendix A, Coding Principles and Standards and Appendix I, Developing Professional Applications with Sheerpower for more on writing professional code in Sheerpower.

Sheerpower has powerful features that make it easy to write short, simple routines:

Routines in Sheerpower

See Section 3.4, ROUTINE/END ROUTINE for more on Routines and Private Routines in Sheerpower.

Each variable in a program belongs to a NAMESPACE. By default, they belong to a "namespace" called MAIN. So:


  abc = 123 
  print abc 

is the same as:


  abc = 123 
  print main$abc 

is the same as:


  main$abc = 123 
  print abc 

Sheerpower supports both ROUTINES that use the MAIN "namespace," and PRIVATE ROUTINES that have their own "namespace." For example:

Example M-1 Routine With Default "Main Namespace"

  show_display 
  
  routine show_display 
    abc = 123 
    print main$abc 
  end routine 

In this ROUTINE, the variable "abc" belongs to the "namespace" of MAIN-sharing its variable names with the main program.

However in this PRIVATE ROUTINE:


  do_totals 
 
  private routine do_totals 
    abc = 123 
    print abc 
  end routine 

the variable "abc" belongs to the "namespace" of "do_totals":


  do_totals 
 
  private routine do_totals 
    abc = 123 
    print do_totals$abc 
  end routine 

Now, let's look at a more complex example:

Example M-2 Private Routines and Namespace

  abc = 123 
  do_totals 
  stop 
 
  private routine do_totals 
    abc = 999 
    print 'The DO_TOTALS version: '; abc 
    print 'The MAIN version     : '; main$abc 
  end routine 
 
  end 

In many programming languages it is difficult to take a large segment of code and break it into separate routines or functions. This difficulty arises from determining how parameters will get passed into and out of the newly created routine. Sheerpower ROUTINES make this task very easy because, by default, ROUTINES have full access to all variables in the code that calls them. For example:

Example M-3 Long code to segment into smaller routines

email_image$ = "c:\sheerpower\samples\emailicon.jpg" 
do 
  email_form$ = '<sheerpower color=#ffaaaa persist>' 
  email_form$ = email_form$ + '<form><title>Send Email</title>' 
  email_form$ = email_form$ + '<img src="' + email_image$ + '"><p>' 
  
  email_form$ = email_form$ + '<table align=center>' 
  email_form$ = email_form$ + '<tr><td align=left><b>From:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=from ' + 
    'value="Type in sender email address here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>To:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=to ' + 
    'value="Type in recipient email address here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>Subject:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=subject ' + 
    'value="Type in a subject here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>Body:</b> ' 
  email_form$ = email_form$ + '<td><br><textarea name=body rows=10 cols=30>' + 
    'Type in the body of the email here</textarea><p>' 
  email_form$ = email_form$ + '</textarea><p></tr>' 
  email_form$ = email_form$ + '</table>' 
  email_form$ = email_form$ + '<p><center>' + 
                '<input type=submit name=submit value="Send Email">' 
  email_form$ = email_form$ + '<input type=submit name=exit value="Quit Email">' 
  email_form$ = email_form$ + '</center></form>' 
  line input dialogbox email_form$: info$ 
  if _exit then exit do 
  for item = 1 to pieces(info$, chr$(26)) 
    z0$    = piece$(info$, item, chr$(26)) 
    name$  = element$(z0$, 1, '=') 
    value$ = element$(z0$, 2, '=') 
    select case name$ 
    case 'from' 
      mailfrom$ = value$ 
    case 'to' 
      sendto$ = value$ 
    case 'body' 
      text$ = value$ 
    case 'subject' 
      subject$ = value$ 
  end select 
  next item  
  if pos(mailfrom$,'@') = 0 or pos(sendto$,'@') = 0 then repeat do 
//  send_email  // commented out so sample program works 
loop 

This code is hard to follow because it has too much detail that the maintenance programmer is forced to read through. So, we can easily segment this code into distinct ROUTINES by:

Programming Keystrokes

See Section F.2, Programming Keystrokes for a complete list of special programming keystrokes available in Sheerpower.

This results in code that looks like:

Example M-4 Correct Program Segmentation

email_image$ = "c:\sheerpower\samples\emailicon.jpg" 
 
do 
  show_email_form 
  if _exit then exit do 
  parse_results 
  if pos(mailfrom$,'@') = 0 or pos(sendto$,'@') = 0 then repeat do 
//  send_email 
loop 
stop 
 
routine show_email_form 
  email_form$ = '<sheerpower color=#ffaaaa persist>' 
  email_form$ = email_form$ + '<form><title>Send Email</title>' 
  email_form$ = email_form$ + '<img src="' + email_image$ + '"><p>' 
  
  email_form_table 
  
  email_form$ = email_form$ + '<p><center>' + 
                '<input type=submit name=submit value="Send Email">' 
  email_form$ = email_form$ + '<input type=submit name=exit value="Quit Email">' 
  email_form$ = email_form$ + '</center></form>' 
  line input dialogbox email_form$: info$ 
end routine 
 
routine email_form_table 
  email_form$ = email_form$ + '<table align=center>' 
  email_form$ = email_form$ + '<tr><td align=left><b>From:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=from ' + 
    'value="Type in sender email address here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>To:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=to ' + 
    'value="Type in recipient email address here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>Subject:</b> ' 
  email_form$ = email_form$ + '<td><input type=text name=subject ' + 
    'value="Type in a subject here"></tr>' 
  email_form$ = email_form$ + '<tr><td align=left><b>Body:</b>' 
  email_form$ = email_form$ + '<td><br><textarea name=body rows=10 col30>' + 
    'Type in the body of the email here</textarea><p>' 
  email_form$ = email_form$ + '</textarea><p></tr></table>' 
end routine 
 
routine parse_results 
  for item = 1 to pieces(info$, chr$(26)) 
    z0$    = piece$(info$, item, chr$(26)) 
    name$  = element$(z0$, 1, '=') 
    value$ = element$(z0$, 2, '=') 
    
    select case name$ 
    case 'from' 
      mailfrom$ = value$ 
    case 'to' 
      sendto$ = value$ 
    case 'body' 
      text$ = value$ 
    case 'subject' 
      subject$ = value$ 
  end select 
  next item    
end routine 

Notice how the program is now easy to follow and therefore easy to maintain.

Unlike the ROUTINE feature whose primary purpose is to break down program code into smaller, more manageable segments, the PRIVATE ROUTINE feature is used to write routines that will be used in a number of different applications. Here is a simple PRIVATE ROUTINE that is used to write messages to a message file:


  private routine write_message with msg 
    if msg_ch = 0 then open file msg_ch: name 'message.log', access output 
    print #msg_ch: time$; ' '; msg 
  end routine 

WRITE_MESSAGE has a single named parameter called "msg." The first time WRITE_MESSAGE is called, msg_ch will be zero, so a new message.log file is created and msg_ch receives the channel#. Then WRITE_MESSAGE writes out the current time and the message.

This PRIVATE ROUTINE can be called from any application without the programmer worrying about variable name conflicts.


  write_message with msg "this is a test" 
   
  private routine write_message with msg 
    if msg_ch = 0 then open file msg_ch: name 'message.log', access output 
    print #msg_ch: time$; ' '; msg 
  end routine 

The PRIVATE ROUTINE feature of Sheerpower is designed to assist in writing routines that will be used in a number of different programs. Variable name conflicts are not an issue because all variable names in PRIVATE ROUTINES have their own private "namespace."


Previous Next Contents Index