naming function problem

To add comments, please log in or register
Bill Morris
287
Bill Morris  

I read http://geosoft.no/development/cppstyle.html#Naming%20Conventions so that my code can look like others.

Now I can't figure out how to name something to coincide with Conventional naming. I know that I can do it any way I want, but I would like my scripts to look like the experts, so that when I'm ready to start programming for others I don't have to deal with questions about my style.

It says

1. "function() names should be verbs" (getName, computerTotalWidth, etc),

2. "there is no reason global variables need to be used at all". Which I assume means replace them with a function call that returns the value.

3. "Complement names must be used for complement operations" (get/set, add/remove, etc).


So now my problem. I have a function that will print or alert a message. I have a boolean variable that determines whether the message should be printed or alerted.

I can't figure out how to set it up to coincide with the conventions.

It would be easy with a global variable:

// Global Variables
bool printSetting = true;    // send message to expert log

//---------------------
bool getPrintSetting()
{
   return (printSetting);
}
//---------------------
void setPrintSetting( bool setting )
{
   printSetting = setting;
}
//---------------------
void logInfo( string msg )
{
   if (printSetting = true)
     Print (msg);
   else
     Alert ( msg );
}

but Conventions says to avoid global variables. And the functions getPrintSetting() and setPrintSetting() are pointless, just change the setting directly by "printSetting = false" anywhere in the script.

It would be easy this way also

void setPrintSetting( bool setPrintSetting )
{
   if (setPrintSetting = true)
     getPrintSetting( "true" )
   else 
     getPrintSetting ( "false" )
}
//---------------------
bool getPrintSetting( string setPrintSetting = "" )
{
   static bool printSetting = true;     // send to Expert log

   if (setPrintSetting = "")
      { }      // do nothing
   else if ( setPrintSetting = "true" )
      printSetting = true;
   else if ( setPrintSetting = "false" )
      printSetting = false;
   else
     Alert ("Invalid Parameter - Print Setting was not changed");

   return( printSetting );
}
//---------------------
void logInfo( string msg )
{
   bool printSetting = getPrintSetting();
   
   if (printSetting)
     Print (msg);
   else
     Alert (msg)
}

but that requires sending a parameter to "getPrintSetting" to tell it to set the variable value, which sounds like a forbidden practice.

Or I could

bool getPrintSetting()
{
   return (printSetting());
}
//---------------------
void setPrintSetting(bool newPrintSetting)
{
   printSetting(true, newPrintSetting);
}
//---------------------
bool printSetting(bool setNewPrintSetting = false, bool newPrintSetting = true)
{
   static bool printSetting = true;      // send msg to Expert Log.

   if (setNewPrintSetting)
     printSetting = newPrintSetting;     
}
//---------------------
void logInfo(msg)
{
   if (getPrintSetting)
     Print (msg);
   else
     Alert (msg);
}

but then the function name (printSetting()) is not a verb.

Again, I know that I can do it any way I want, but how do the experts do it?

Ubzen
5298
Ubzen  
My Advice: You're trying to do too much. There are NO standards around here. Mql(x) is Not a religious language with die-hard following. I'm not a career programmer and never would be. But from all the codes I've seen around here, I'd say you'd be better off doing it the way you want. Let others who are going to modify your codes in the future worry about their standards.
Bill Morris
287
Bill Morris  
ubzen:
My Advice: You're trying to do too much. There are NO standards around here. Mql(x) is Not a religious language with die-hard following. I'm not a career programmer and never would be. But from all the codes I've seen around here, I'd say you'd be better off doing it the way you want. Let others who are going to modify your codes in the future worry about their standards.
Yeah, I've been reading more and came close to realizing the same thing. I think I'm going to stick with the conventions I have been using other languages. If or when others are seeing my code, I'll spend the time to convert them to a more typical MT4 style.
William Roeder
18698
William Roeder  
The 'no globals' is generally correct, the less the better. If you look at my code you'll see lots and they come in 3 flavors:
  1. Set by functions, used in start's comment. These are just me being lazy. I could have made those variables local to start and passed them down by reference to be returned. (I never said my code is a good example of coding style, only an example with a lot of mql4 functionality.)

  2. Set by some function, used by others, hidden from caller's. This is information hiding which is a good thing. If the caller doesn't need to know about the details, they should be hidden. C++ uses objects to hide details while C programs would use a typedef of a pointer to a struct. An example in my code is SetDIR sets DIR, op_code, etc. while MaximumDIR uses DIR to do a max on buy or min on sell.
  3. The third is due to the fact that the main program loop is outside of our code. If you need to keep values as the program runs, normally you would define a variable in main and pass it down to other functions. But in Mlq4 we must return from start. The choice then becomes either static variables in start passed down or global variables implicitly passed down.
In your example, you are trying to hide information, I would code it like this:
// Logging Functions
bool logJournal = true;    // send message to expert log
void setlogJournal(bool setting){ logJournal = setting; }
bool getlogJournal(){             return (logJournal);  }
void logInfo( string msg ){
   if (getlogJournal()) Print(msg);
   else                 Alert(msg);
}
The caller of logInfo doesn't care where the message goes, he just calls it. Then if you change it to:
// Logging Functions
bool logJournal = true;    // send message to expert log
bool logScreen  = false;   // send message to the screen
void setlogJournal(bool setting){   logJournal = setting; }
void setlogScreen(bool setting){    logScreen = setting; }
bool getlogJournal(){               return (logJournal);  }
bool getlogScreen(){                return (logScreen);  }
void logInfo( string msg ){
   if (getlogJournal()) Print(msg);
   if (getlogScreen())  Alert(msg);
}

Now you have more functionality, but the caller of logInfo still doesn't care.


I also use a naming convention. My pattern: global variables have dots. Captialized with dots are externals. Mostly the dots are used in C++'s object.member style (TSSF, TSSF.max)

No dots are local variables. I use underscores as spaces for all caps constants (OP_BUY)


Conventions are good, but they're not gospel. Use them to make the code clearer.
Bill Morris
287
Bill Morris  
WHRoeder:
The 'no globals' is generally correct, the less the better. If you look at my code you'll see lots and they come in 3 flavors:
  1. Set by functions, used in start's comment. These are just me being lazy. I could have made those variables local to start and passed them down by reference to be returned. (I never said my code is a good example of coding style, only an example with a lot of mql4 functionality.)

  2. Set by some function, used by others, hidden from caller's. This is information hiding which is a good thing. If the caller doesn't need to know about the details, they should be hidden. C++ uses objects to hide details while C programs would use a typedef of a pointer to a struct. An example in my code is SetDIR sets DIR, op_code, etc. while MaximumDIR uses DIR to do a max on buy or min on sell.
  3. The third is due to the fact that the main program loop is outside of our code. If you need to keep values as the program runs, normally you would define a variable in main and pass it down to other functions. But in Mlq4 we must return from start. The choice then becomes either static variables in start passed down or global variables implicitly passed down.
In your example, you are trying to hide information, I would code it like this: The caller of logInfo doesn't care where the message goes, he just calls it. Then if you change it to:

Now you have more functionality, but the caller of logInfo still doesn't care.


I also use a naming convention. My pattern: global variables have dots. Captialized with dots are externals. Mostly the dots are used in C++'s object.member style (TSSF, TSSF.max)

No dots are local variables. I use underscores as spaces for all caps constants (OP_BUY)


Conventions are good, but they're not gospel. Use them to make the code clearer.

I read some more and decided that going out of my way to avoid global variables was not the way to go, so I gave up trying to find a way to avoid them. It just doesn't make sense to me to create 3 functions just to avoid using a global variable (set/get & a function to hold the static variable which violates the convention that function names should be verbs).

I can't think of a reason to hide this kind of global variable from callers.

I do have a situation where I want to restrict access to a variable only to the file it's initialized in. I figured out how to do that by just putting the #include statement at the bottom of the calling file, but that created more problems than it solved. I really miss the "private" scope from VBA.

To add comments, please log in or register