SRL Archive - FAQ

Is this by design?


Bixby Sayz

2014-02-28 09:29:55

Ran into this nasty "gotcha" using Lape:

program new;

type
TMyType = record
X: Integer;
Y: Integer;
end;

procedure TMyType.Assign(const X, Y: Integer);
begin
WriteLn(Format('Assign Params: %d, %d.', [X, Y]));
Self.X := X;
Self.Y := Y;
end;

procedure TMyType.Assign2(const XValue, YValue: Integer);
begin
WriteLn(Format('Assign2 Params: %d, %d.', [XValue, YValue]));
Self.X := XValue;
Self.Y := YValue;
end;

var
MyVar: TMyType

begin
MyVar.X := 1; MyVar.Y := 2;
WriteLn(Format('MyVar - Before Assign: %d, %d.', [MyVar.X, MyVar.Y]));
WriteLn('>> Passing 3,4 to Assign()');
MyVar.Assign(3, 4);
WriteLn(Format('MyVar - After Assign: %d, %d.', [MyVar.X, MyVar.Y]));
WriteLn('>> Passing 5,6 to Assign2()');
MyVar.Assign2(5, 6);
WriteLn(Format('MyVar - After Assign2: %d, %d.', [MyVar.X, MyVar.Y]));
end.

MyVar - Before Assign: 1, 2.
>> Passing 3,4 to Assign()
Assign Params: 1, 2.
MyVar - After Assign: 1, 2.
>> Passing 5,6 to Assign2()
Assign2 Params: 5, 6.
MyVar - After Assign2: 5, 6.
Successfully executed.


If the name of the parameters in the function/procedure match the names of properties of the datatype the the values passed in are ignored. Holy Crap! That took me three very painful hours to figure out what was going on. The code looked right but didn't behave as expected. Can you say "We need a debugger"? I knew you could."

Frement

2014-02-28 09:56:14

Thats because in the function, anything in "Self" belongs to that scope. Basically, you can do X := XValue; and it would be the same as Self.X := XValue;

So naturally X would be already defined in the scope.

Bixby Sayz

2014-02-28 10:06:26

???

So if I explicitly (first assign example) pass in named parameters they get ignored? That boggles my mind.

I've run into a similar situation where if the name of a local variable inside a function/procedure matches the name of a global variable Simba sometimes references the global variable and not the local variable inside the function/procedure. Just plain nasty and hellishly difficult to track down.

masterBB

2014-02-28 11:58:49

From: Bixby Sayz
So if I explicitly (first assign example) pass in named parameters they get ignored? That boggles my mind.


It is basically like

function TType.YourFunct(): Boolean; 
begin
With(Self) do
begin

end;
end;

Anyway, in most language you use underscores in the parameter names if they match the base type its variables.

Brandon

2014-02-28 12:37:55

^ In C & C++ and quite a few more languages, variables beginning with a _, L, __, and a couple other symbols is actually illegal and reserved by the standard; as well as variables that have a double underscore anywhere within in them. It is okay for Lape though.


Java of course hereditarily adapts this notion of discouraging use of the _ and other symbols on variable names as quoted here: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html#Naming


The rules and conventions for naming your variables can be summarized as follows:

Variable names are case-sensitive. A variable's name can be any legal identifier — an unlimited-length sequence of Unicode letters and digits, beginning with a letter, the dollar sign "$", or the underscore character "_". The convention, however, is to always begin your variable names with a letter, not "$" or "_". Additionally, the dollar sign character, by convention, is never used at all. You may find some situations where auto-generated names will contain the dollar sign, but your variable names should always avoid using it. A similar convention exists for the underscore character; while it's technically legal to begin your variable's name with "_", this practice is discouraged. White space is not permitted.

Subsequent characters may be letters, digits, dollar signs, or underscore characters. Conventions (and common sense) apply to this rule as well. When choosing a name for your variables, use full words instead of cryptic abbreviations. Doing so will make your code easier to read and understand. In many cases it will also make your code self-documenting; fields named cadence, speed, and gear, for example, are much more intuitive than abbreviated versions, such as s, c, and g. Also keep in mind that the name you choose must not be a keyword or reserved word.


If the name you choose consists of only one word, spell that word in all lowercase letters. If it consists of more than one word, capitalize the first letter of each subsequent word. The names gearRatio and currentGear are prime examples of this convention. If your variable stores a constant value, such as static final int NUM_GEARS = 6, the convention changes slightly, capitalizing every letter and separating subsequent words with the underscore character. By convention, the underscore character is never used elsewhere.



From: Bixby Sayz
Ran into this nasty "gotcha" using Lape..

If the name of the parameters in the function/procedure match the names of properties of the datatype the the values passed in are ignored. Holy Crap! That took me three very painful hours to figure out what was going on. The code looked right but didn't behave as expected. Can you say "We need a debugger"? I knew you could."



This is a bug/flaw in my honest opinion. In every language such that the parameter name matches the internal name, the parameter name should always have scope authority access over the internal name. So it is written in Java and many other high-level languages.

There is a reason for the self/this keyword. It should allow access to the internal name which is hidden by the parameter name. In Lape's case, it makes no difference here because whether or not you use self, it is still accessing the internal name and thus access to all local scope/parameter scope variables is lost in translation.

Compilers usually give a warning about the parameter hiding a variable belonging to "this". In Lape's case, it will leave you be lol. It is certainly a design flaw/bug.

For specifically this reason, Lape needs a "scope" operator + self. Scope operator for accessing global variables & functions hidden by overridden or local variables and self for accessing internal variables hidden by parameters, local, or global variables.

I can't remember if using Of Object fixes this or not or some other problem.

Gu3st...

2014-03-02 22:03:53

This is nielsie's response to when I brought up this problem in the lape-thread
From: nielsie95
This is something I've wanted to fix. It requires static type functions and is harder to implement than I initially hoped.