public and private modifiers for variables in access form module - ms-access

I have a form module in my access project. In the top of the module, I declare a variable like so:
option explicit
private id_foo as long
I want to explicitely state that I need the variable in my form module by using the private access modifier on it.
Now, further down in the same form module, I have a function that needs to know and/or modify the value of id_foo:
function bar() as long
call do_something(me.id_foo)
end function
Yet, this doesn't work. But when I change the private modifier to a public modifer like
public id_foo as long
it does work.
This behaviour strikes me as odd or unintuitive, and, in fact, I can't see the meaning of public and private if I have to declare the variable as public anyway in order to use it in the same form module.
So, am I overlooking something obvious or is this how it is supposed to be?
Thanks / Rene

Try it without the "me" in front of id_foo:
function bar() as long
call do_something(id_foo)
end function

If you use the me keyword, you can see only public members, properties (also Form and VBA).

A form along with its module actually represents a class object. You can also create (instanciate) multiple Instances of that class object.
So, Any variable you declare as public becomes a public property of that class object. Note that any function in the forms code module declared as public becomes a public method of that class object. All of these properties and methods then show up in the intel-sense when you type in the "me." keyword.
If you declare the variable as private, then that variable (or function) will not be exposed as a public property (variable) or a public method (function) of the form.
So the simple solution your cases is to drop the use of the me keyword in your code, and it you code will run just fine at.
So declaring as public or private does have an effect here. In fact, “private” is the default.
So, public will expose the variable and/or functions as properties and methods of that form which is a class object (note that you can have Multiple instances of the same form loaded at the same time).
If you decleare things as private (the default, so you don’t have to do anything for the Variable or function) then you can still use the value in ANY code routine in that forms code module, but it will not be public exposed as a property/method and thus you can't use me.
Thus, your code will work fine if you remove the use of the me., and just go:
function bar() as long
call do_something(id_foo)
end function

Related

Must class constructor variables be assigned to private class variables or is there a less code intensive way?

When creating a class you have to assign its parameters to private class variables in order to use those private variables in other procedures and functions in the class. This is code intensive since you have to define the same variable twice.
I have tried using a constructor parameter in a procedure of the same class but it did not work without having to
type
WorldObject=class
private
privX, privY, privStartSpriteNum, privEndSpriteNum:word;
privDirection, privTurn:byte;
public
constructor create(x, y, startSpriteNum, endSpriteNum:word; direction, turn:byte);
procedure draw;
constructor WorldObject.create(x, y, startSpriteNum, endSpriteNum:word; direction, turn:byte);
begin
privX:=x;
privY:=y;
privStartSpriteNum:=startSpriteNum;
privEndSpriteNum:=endSpriteNum;
privDirection:=direction;
privTurn:=turn;
end;
procedure WorldObject.draw;
begin
writeLn(privX);
writeLn(WorldObject.x);
end;
Was expecting writeLn(WorldObject.x) to print the value of x.
But got the error: Identifier idents no member "x".
Is there not a way to use the parameter variables from the constructor without having to pass them to private variables?
Thanks!
You seem to be hoping that there is a mechanism where parameters to constructors are automatically stored somewhere, for retrieval later. There is no such mechanism. It is your responsibility to store any state that you need to refer to outside the scope of your constructor. Using fields of your class is the classic method to do this.
You can write properties instead of copying private variables, you just need to specify where to read and where to write, since then you can use properties in nested classes or even outside the class.
If you need to use them in the nested classes, declare as protected, if not - as public.
property MyProp: TYPE read WriteMyProp read GetMyProp; // for procedure to write and function to read;
property MyPropV: TYPE read MyPropValue write MyPropValue; // for deriving from variable;

AS3 create a variable in root from within a function

I have a fairly big swf right now with a bit of coding already. Most vars are created in the root, but now I have a problem.
I want to reload the flash swf (reset), and for that, I need to create a function that destroys all the vars and another one that creates them. At the moment, I have a javascript function that reloads the page, but that really isnt a good solution.
The problem is that when I create a var inside a function, it doesn't get created in "MovieClip(root)", and instead is only related to the function, thus rendering my swf unable to work.
Is there a way to create vars in MovieClip(root) from within a function? Or is there an alternative to what I'm trying to do?
EDIT: Added some example code.
function SetVar():void{
var test:String= new String("foobar");
}
SetVar();
trace(test);
...and the output is:
Scene 1, Layer 'Layer 1', Frame 1, Line 7 1120: Access of undefined property test.
Which is normal, because the "var test" is not global, so it was lost when the function ended. I want to make it so the function "SetVar()" adds the vars to the root, or global.
You need to read up on how scope works.
Basically:
An object declared within another object (be it a Class, Function, Object, or Loop), is only available within that specific object or loop iteration.
Object scope is inherited by children, not by parents. So a function within a class has access to an object declared within that class, but a class does not have access to an object declared within a function
A parent (or any other object) can access objects declared within child classes, but only if it is a public object
So looking at those basic rules (they are very, very basic. If you are just starting out, I urge you to do some proper research into object scope in OOP. It is the basis of everything you will do in dozens of languages), you are declaring an object in a function and trying to access it from outside that function. This breaks Rule #1 from above.
Instead, try this:
var test:String;
function setVar():void{
this.test = 'foorBar';
}
trace(test); //output: null (undeclared)
setVar();
trace(this.test); // output: fooBar
Looking at this, I did two things:
I moved the declaration of test into global space, meaning any object in that object will have access to it
I renamed SetVar to setVar. This has nothing to do with your question, but in AS3, the standard naming conventions dictate you use lowerCaseCamelCase for all objects (including functions), UpperCaseCamelCase for all Class names, and lowercasename for all package names. Again, unrelated but it is good to learn.
Now, ideally, you would probably want to do that setVar function slightly differently. To allow for better abstraction (basically making your code as generic an reusable as possible), you would want to return the value from the function rather than manually set the variable in the function.
var test:String;
var anotherTest:String;
function setVar():String {
return 'foorBar';
}
this.text = setVar();
this.anotherTest = setVar();
trace(this.test); // output: fooBar
trace(this.anotherTest); // output: fooBar
So that allows you to use that function with any String variable imaginable. Obviously, that is not very useful here since it doesn't do any logic. But I am sure you can see how that could be expanded with more code to make it more dynamic and much more useful
EDIT: As an afterthought, I used the this keyword. In AS3 (and a few other languages), this refers to the scope of the current class (or current frame, in case of timeline frame coding). So this.test refers to a variable test declared in the scope of the frame or class.
I am not entirely sure what you are looking for because there is no code associated with your question. However I will impart a bit of information I feel relates to the subject.
if you declare your variables in the class then you can reference them from a function as such:
package{
import flash.display.MovieClip;
public class DocumentClass extends MovieClip{
public var example:String = 'dog';
public function DocumentClass(){
trace(example); // dog
testFctn();
trace(example); // frog
}
public function testFctn(){
example = 'frog'
}
}
}
if you want to reference the variable of a parent class this.parent['variableName'] can be useful too. or a sibling of your working class sharing a parent class, this.parent['childClass']['variableName'] ...
Since you are declaring the variable within the function, its scope is restricted to that function only.
Try declaring the variable outside the function and initializing it in the function instead.
You should then be able to access it from root.
But if you wish to declare a variable on root from within a function (highly unusual requirement) then you can try doing:
document["variableName'] = value;
or
root["variableName'] = value;
inside the function.

AS3: inline way to write get and set?

I was reading a tutorial and the user there was starting setters and getters like so
function get f():Number;
function set f(value:Number):void;
inside an interface, then saving it in the main file inside a variable
var testNode:INode;
and referencing them as
testNode.f;
I thought this was really handy, specially for when you have a lot of variables. Instead of having to create two functions for each private value.
However, I tried to do the same without instancing the get and set inside an interface (because I had no need for this) and I get an error saying the function doesn't have a body.
Why is that? Is there any way to write get and set in such a clean, short manner? So far I've been writing these as
public function get someVar():SomeClass {
return _someVar;
}
public function set someVar(newValue:SomeClass):void {
_someVar = newValue;
}
but it's a bit of a hassle when I have several private variables.
An interface is just a model for your class, it does not allows you to skip the definition of a function (or a getter/setter). You must declare the getter and the setter in any class implementing your interface. What you are looking for is an extension (inheritage).
If you define a class Mother.as with a getter and a setter, the class Child.as which extends Mother.as doesn't need to redefine the getter and setter.
Furthermore, if you don't plan on writing anything else inside the getter and setter, you should use a public variable. These are less resource consuming than useless get/set.

trouble accessing non-static functions from static functions in AS3

I have a class containing, among other things, a drop down menu. With the aim of saving space, and since the contents of the menu will never change, I've made a static DataProvider for the whole class that populates each instances menu. I was hoping to populate the list with actual functions like so:
tmpArr.push({label:"Details...", funct:openDetailsMenu, args:""});
and then assign tmpArr to the DataProvider. Because the DataProvider is static the function that contains that code also needs to be static, but the functions in the array are non-static. At first it didn't seem like a problem, because when the user clicks on a menu item the drop down menu can call a non-static "executeFunction(funct, args)" on its parent. However, when I try to compile, the static function setting up the DataProvider it can't find the non-static functions being passed. If the compiler would just trust me the code would work fine!
The simple solution is to just pass strings and use a switch statement to call functions based on that, but that's big, ugly, inelegant, and difficult to maintain, especially if something inherits from this class.
The simpler solution is to just make the DataProvider non-static, but I'm wondering if anyone else has a good way of dealing with this? Making the static function able to see its non-static brethren?
Thanks.
OK, the basic reason for making things static is if you want to make it independant of an instance, for example the Math functions in as3 (you call Math.min() as opposed to var math = new Math(); math.min()...) this is useful for reference, repetetive calculation, simple actions (add 10 to x value) etc.
the problem with combining static and non static functionality is that when calling a static function, there is a possibility that the class has no instance at that point, or (in this case) that there is any reference to the function that would make sense in compilation (if a seperate class called the function, how would it reference openDetailsMenu?).
what you need to do is either go through getting function by name (object"functionname" works for example), make annonymous functions in your array or alternatively add a callback method to your static function something similar to this:
public static function doAction(object:Menu, event:String){
if(event == "details") object.openDetailsMenu() ;
}
all in all you are just adding layers of complexity that isnt really going to help. if you just add a class function and get them all to do the same action it is not taking more space or effort than if you are calling to a static function. you need to think about how and why the function is going to be used in (or out of) the class.
you could just store a static reference to the instance, in this case _instance. ( Kind of like a ghetto singleton ) just be careful not to call the static method before the class has been instantiated.
/// in your constructor define a static reference handle to the instance
public function ClassName(){
_instance = this;
}
public static function doSomethingStatic(){
var varValue = ClassName._instance.someInstanceVariable;
}

Copy constructor using private attributes

My first question here so be gentle.
I would like arguments for the following code:
public class Example {
private String name;
private int age;
...
// copy constructor here
public Example(Example e) {
this.name = e.name; // accessing a private attribute of an instance
this.age = e.age;
}
...
}
I believe this breaks the modularity of the instance passed to the copy constructor.
This is what I believe to be correct:
public class Example {
private String name;
private int age;
...
// copy constructor here
public Example(Example e) {
this.setName(e.getName());
this.setAge(e.getAge());
}
...
}
A friend has exposed a valid point of view, saying that in the copy construct we should create the object as fast as possible. And adding getter/setter methods would result in unnecessary overhead.
I stand on a crossroad. Can you shed some light?
Access is class based, not object based.
The rationale for making a member private is that the ther classes should not know the details of implementation outside of well defined API, so as to make the rest of the system tolerate the change of implementation. However, the copy constructor is not "the rst of the system" - it is your own class.
The first example is not copying a private attribute of an instance, because they are bot instances of the same class.
However, if you add access methods/properties, any decent compiler should optimise them away to simple "inlines", in which case the second method is cleaner code (all accesses go via your access function) but both approaches should end us as be equally efficient (probably identical) memberwise copies.
If you really want a copy constructor to be efficient, then a lower level binary copy will be faster than a memberwise copy. But significantly "dirtier".
In general I prefer to access all member fields via properties/accessors as that encapsulates them better, allowing you to change the underlying implementation/storage of a field without having to change any of the code that accesses it, except for the property/accessor itself.