Name collision with undocumented symbols.
o The Environment:
Windows 10
Eclipse Neon.3 (4.6.3)
ConnectIQ SDK 2.3.4
o A detailed description of the issue
If you run the below code below, you will see that the numbers being output vary based on context. When I run the testcase under the simulator, I get...
App 2
View 2
Delegate 1
In this case it is because Ui.InputDelegate has an undocumented member with the same name (BEHAVIOR_NEXT_PAGE), and when in a derived class the name in the base class is found before the one declared by me at global scope.
A quick search through api.debug.xml exposes the name collision.
It seems that the implementation should not be exposing these symbols to the user. In some cases it might work to declare the data as private, but it is likely that the implementation needs access to variables or constants in derived classes, so that isn't really an option.
One convention for avoiding this problem is to document that names that match an expression are reserved for the implementation, and the user should never use or reference identifiers with those names. In C/C++ any name that starts with an underscore and is followed by a capital letter or another underscore, is reserved. i.e., a user should never name a variable __idx or _Count.
Yes, it does make implementation code a bit more difficult to read, but it avoids unexpected problems for users.
o Steps to reproduce the issue
Build and run below test case. You should see the output differs for code executed in the delegate initialize method.
o Any applicable additional information
N/A
o A code sample that can reproduce the issue (in email only if preferred)
using Toybox.Application as App;
using Toybox.Lang;
using Toybox.System as Sys;
using Toybox.WatchUi as Ui;
enum {
BEHAVIOR_BACK,
BEHAVIOR_MENU,
BEHAVIOR_NEXT_PAGE,
BEHAVIOR_NEXT_MODE,
BEHAVIOR_PREVIOUS_PAGE,
BEHAVIOR_PREVIOUS_MODE,
BEHAVIOR_SELECT
}
// note that I'm not using the print line function below because vBulitin won't let me post the code if I do...
class TestDelegate extends Ui.BehaviorDelegate
{
function initialize( ) {
BehaviorDelegate.initialize();
Sys.print("Delegate " + BEHAVIOR_NEXT_PAGE + "\n");
}
}
class TestView extends Ui.View
{
function initialize( ) {
View.initialize();
Sys.print("View " + BEHAVIOR_NEXT_PAGE + "\n");
}
}
class TestApp extends App.AppBase
{
function initialize( ) {
AppBase.initialize();
Sys.print("App " + BEHAVIOR_NEXT_PAGE + "\n");
}
function getInitialView( ) {
return [ new TestView(), new TestDelegate() ];
}
}