Developer help - hollie/misterhouse GitHub Wiki
This page is intended to provide hints and tips for developers.
Why is my code not working
Many errors are flagged by MisterHouse on a Reload, but some can be difficult to spot.
Here is a list of common errors in Perl code which you can check for.
- Perl code is case-sensitive. Check your capitalisation. In MisterHouse, 
$Dayis right, and$dayis wrong. - Commands end with ;     But there should be no ; at the end of a line starting a 
doloop, anif, or a sub-routine. - Unmatched parentheses, curly braces, quotes and delimiters.
 - A line starting with 
ifrequires the condition to go between parentheses, egif (time_now('2:00 PM')) { } if ($string = "abc")is wrong. The correct syntax isif ($string eq "abc")if ($number = 1)is wrong. The correct syntax isif ($number == "abc")- Many perl scripts (including the code in MisterHouse) start with 
use strict;This means that new variables must be pre-declared as$my variable. This error is flagged asOops1: Global symbol "$variable" requires explicit package name at (eval 57) line 1056. (See below for a point on this which is specific to MisterHouse) - When declaring more than one variable, use parentheses: 
my ($variable1, $variable2); - VB programmers may accidentally type 
string$instead of$string - A very long line may appear to have a carriage return at the end, but not have a carriage return at the end
 #(which starts a Remark statement) may appear to be the first character of a line of code, but in fact be in the middle of a line of code- A dot may be missing before or after 
"or= - It is easy to forget to put 
\before/or\or$or.or"or@etc - In Windows and DOS, file-paths are typed as 
c:\filepath. In Perl this must appear asc:/filepathor (in some contexts for Windows users)c:\\filepath (or[might be typed when{is required (etc)- It is easy to forget 
~after=in matches and substitutions - Wrong number of arguments in subroutines
 - Local variables lose their values outside their own section of code. A global variable should not be declared inside a sub-routine.
 foreachmust be typed, notfor eachforeach $item (@list)is right.foreach $item @listis wrong.- In a substitution, 
s/(text1).+(text2)/may fail by looking too far ahead. You may have meants/(text1).+?(text2)/. The?tells Perl to keep the number of characters betweentext 1andtext 2to a minimum. - dot in a match will not match 
\nunless you use the/smodifier - A match or substitution in a string containing newlines may fail if you forget the 
/smodifier at the end - Arrays start at 0 not 1
 
This is a vital point which applies only to MisterHouse, not to Perl generally.
A new variable in a loop module is taken out of the loop if it is typed in the first column on the left of the screen.  This is not a problem if the value of the variable is fixed from the outset (eg my $sky_color = 'blue'), but will cause an error if the value of the variable is based on the value of another variable, my $circumference = $radius * 3.14. A line like this must be indented by at least one space.
INI PARAMETERS
All the entries in mh.ini are read on MisterHouse Startup and on a Reload. They are stored in the %config_parms array. So, for example, if you added:
  myparm1=a b c
This will be available as $config_parms{myparm1}
Logging
These docs refer to MisterHouse versions after pull request #820 where print_log was renamed to print_log_simple and the new print_log was created which allows the developer to call print_log with 3 parameters e.g.
print_log("this is my message","WARNING","my subroutine")
Will produce an entry in print.log like this;
13/01/2021 17:08:06 [my subroutine] WARNING: this is my message
The second parameter severity should be one of EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL, NONE or DEBUG, if NONE is set, the print_log_private() should just return and not print anything.
If MisterHouse cannot find a print_log_private() subroutine, it will pass the message concatenated with the severity and source to print_log_simple.
If you have created a print_log_private() subroutine, then your subroutine will be called instead of passing the message to print_log_simple.  You can then decide on the destination of the message (email, SMS, twitter, whatever) or even the print_log_simple() subroutine.
A sample print_log_private() is provided in mh/code/examples/print_log_private.pl.
See here for the logging function definitions.