Safely to declare and initialize a global variable in a monticello package? - smalltalk

How can you safely declare and initialize a global variable used by a Monticello package so you don't get errors during loading? Is doing
Smalltalk at: #VarName put: varValue
in a class-side "initialize" method of one of the package classes enough? (I would prefer not to use shared pools in this case.)

Yes, that's enough. Another option would be to use lazy initialization:
^ VarName ifNil: [ VarName := value ]
I'm curious, why are you using a global variable? In my experience there are only very few cases which can't be solved without using global variables and it is my opinion that in most cases the use of a global variable is a hint for bad design.

Related

How can I use access specifiers on member variables in a function block in structured text? (Beckhoff, TwinCAT)

An important part of OOP is to use access specifiers to make member methods and variables inaccessible from outside of the object.
When declaring a function block method is is easy to control the Access Specifier, but I have not found a way to control access to member variables.
Is it possible and if yes, how?
You can actually still access internal variables of an object direcly in code (no pointers), but they are read only. The code completion will not display the internal variables though, but after you finish typing the name structure, you will see no compile errorrs - test := fb1.internalVariable will be a valid read action actually while fb1.internalVariable := 5; will end up giving you an error, saying that the variable is not an input to the function block (or any other object for that matter).
You can also use the hide oder hide_all_locals pragma to suppress local variables being found in auto-complete and crossreference-list (see https://infosys.beckhoff.com/content/1033/tc3_plc_intro/2529654667.html?id=5927203996458905204 )
Every variable that you declare under the VAR section of your Function Block is considered private.
There is no public or private keyword for variables in IEC 61131-3
Another thing you can do if you absolutely want to use public/private keywords is to define properties.
In general, the normal convention is to have read-only variables in the VAR_OUTPUT section of the Function Block and writable variables in the VAR_INPUT section of the Function Block. Again, the VAR section is considered a private section even though you could read this variables with the fbName.var notation or write them through their address (but this is a very bad programming style).
Twincat2 also allowed the variables in the VAR section to be written to with the fbName.var notation but this changed in Twincat3 in order to achieve better incapsulation.
To learn more about programming conventions in the IEC 61131-3 world, I recommend you to read the programming guidelines of the PLCOpen organization:
https://plcopen.org/guidelines/guidelines

why can't perl6 just autovivify so that I don't have to use "my" all the time?

In per5, I can just use a variable, such as $foo or #bar without using "my".
$foo=1; #bar=(1,2);
In perl6, why do I have to use "my" all the time? Otherwise compiler will say variable undeclared.Why can't perl6 just autovivify?
print "{my #a=1,2,3;}\n"; # have to use "my" to declare variable
print "{#a=1,2,3;}\n"; # this is error 'Variable '#a' is not declared'
I don't like the restriction of having to always use "my". This is too low level like C; very cumbersome.
Is there a way to turn on always autovivify?
Thanks.
Not having explicit variable declarations is a terrible idea from the perspective of language design for various reasons. Arguably, explicitly declared block-scoped lexical variables are the way to go, and I find it crazy how many languages of the 'scripting' variety get this 'wrong' (there's a reason why let got added to Javascript...)
That said, Perl6 supports the no strict pragma which allows you to omit the declaration.
no strict;
$foo=1; #bar=(1,2);
print "{#a=1,2,3;}\n";
# OUTPUT«1 2 3␤»
Perl 6 tries to help you with proper error messages. If you declare all variables it will provide you with a guess what variable you meant if you have a typo. Also there are new language features like constants and sigilless variables that are not possible to write down without declarators.

What is the most proper way to declare global variable to use for many modules in Fortran?

The question is: If I want to use global variables in many modules. How should I do?
In my opinion, I think, maybe we could make another module and declare the global variables and then include it to any files that require it or something like that. I think this is a very simple way but the problem is I'm not familiar with Fortran. I don't know how to do it and how normally people do it.
Please give me some easy example.
You can just make a module, perhaps called global
module global
implicit none
real :: my_global_x
integer :: my_global_i
end module
and then you can use it wherever it is needed, in modules
module a
use global ...
end module
in subroutines
...
subroutine s
use global
...
end subroutine
...
or in the main program
program main
use global
implicit none
...
end program
You can also use just a limited number of variables from the module to avoid name-space pollution
use global, only: my_global_x

Global variable initialization & finalization

I have a critical section that is shared between two threads:
TCriticalSection lock_measDataBuff;
I have declared this variable as global. Now because Delphi style classes must be constructed using operator new, i have modified above declaration as follows:
TCriticalSection *lock_measDataBuff;
Where is the best place to initialize the lock variable using operator new? Where is the best place to finalize the global variable using operator delete? Should it be WinMain method? Constructor of one of the classes accessing lock variable? Or some other place in the code?
I would use std::auto_ptr or boost::unique_ptr to handle all of that for you, eg:
#include <memory>
std::auto_ptr<TCriticalSection> lock_measDataBuff(new TCriticalSection);
As you are creating a global variable, you will need to initialize before you create the threads, which would be main, and the best place to release the memory would be after the threads end

How to initiate global variable in Squeak

I don't mean a class variable. I want a variable that can be used everywhere. How should I initiate it?
I know one way is Smalltalk at: #variableName put: theValue. but I don't want to give it value as soon as I create it.
This should do the trick:
Smalltalk at: #VariableName put: nil
When you create a global variable in the Smalltalk dictionary, you are creating an Association which has a key and a value, so you can't get away without providing some sort of value.
You can come back later and change the value with:
Smalltalk at: #VariableName put: newValue
Any compiled code that references the global variable will see the new value, because the compiled code references the Association.