Object Inheritance

Our team is new to Eggplant. We are used to working in an OOP framework, and are looking forward to working with the Sense Talk language to accomplish our tasks.

One thing that appears a little confusing so far is the absence of inheritance. While it appears that objects can be aggregated, there is no true inheritance occurring. Specifically, I would like to create an object that has some constant variable names and basic functions that a set of scripts can inherit. A helper object does not appear to be the way to go here simply because we need to have name constant variables passed to the derived object.

Any ideas? Am I missing something important? Thanks for the help!!

SenseTalk is an object-oriented language, but it is not class-based, so it doesn’t support “inheritance” from a class hierarchy in the same way that languages like Java, C++, or Objective-C do. Instead, each SenseTalk object is a distinct entity, with its own properties and behaviors.

There is a form of inheritance in SenseTalk, though, which works through the “helper” mechanism. Any object can have a list of helper objects from which it can inherit behaviors. If the primary object doesn’t have a handler for a given message, each of its helpers in turn is given a chance to “help it out” by handling that message on its behalf.

The helper mechanism is probably what will best serve your needs, but I’m a little unclear on exactly what you mean by “constant variable names” – can you give an example of what you’re looking for?

Sorry for taking so long to respond.

The problem is that I have a file of values:

ValueX: SomeValue,
ValueY: SomeOtherValue,

etc.

I need this list of values to be available to objects only under specific instances. In other cases, it must not be made available, so there is some decision branching occurring.

We’ve set up our test framework in a very modular fashion, with certain script objects performing specific functions. It may be that in each script object I need some logic like:

if condition A
start using scriptA
else
start using scriptB

where scripts A and B have global variables defined. I’m hesitant to go that route, but I recognize that this may be the only way to solve this particular problem.

Taking a modular approach is a very good idea. There are a number of different ways to make different sets of values available in your scripts. Here’s one idea that you might want to consider, that uses your basic approach of storing values in different files.

For each set of values that you may want to load, create a file that’s formatted like this:

{
ValueX: SomeValue,
ValueY: "Some Other Value",  -- you can include comments if you like
}

Any value that contains spaces or special symbols should be enclosed in quotes (to be safe, just enclose every value in quotes).

Near the beginning of your main script, do this:

set global constants to (:) -- an empty property list

Then, whenever your script reaches a point where it determines that a particular set of values should be available, you might have code like this:

 if conditionA 
    add properties of (value of file "/path/to/dataSetA") to global constants
else
    add properties of (value of file "/path/to/dataSetB") to global constants
end if

You can then access these constant values whenever you need to:

put global constants.valueX into importantValueToUse

Any value that hasn’t been set will just be empty.

If you don’t want to have to use the word “global” everywhere that you access your constants, you can declare the variable “constants” to be global near the beginning of each handler:

global constants

Does this approach seem like it might serve your needs? It’s not directly related to objects, although you could set your constants from properties of an object instead of reading them from a file if that made more sense in your situation.

I’m afraid trying the code as posted above did not add the values to the global array.

Specifically, I tried:


set global constants to (:)

add properties of (value of file "/full/path/to/script.script") to global constants

and in doing so, I received the following error:

Invalid Parameter – destination of Add Properties command must be an object that is modifiable

So, apparently I am still missing something important. Changing global constants to me did prevent the above error, however the properties were not actually added.

Any advice?

The code works fine for me just as you posted it (only changing the file path to point to a valid data file). I tried every variation I could think of, and I’m puzzled as to why this isn’t working for you. Did you by any chance have more code that you didn’t show here that might have set global constants to something else in between the two lines shown here?

What version of Eggplant are you running?

What exactly are the contents of the file you are accessing (although you should see a different error if this is where the problem is)?

The data file is formatted as follows:


{
ValueA: "ImageDirectory/Image",
ValueB: "ImageDirectory/ImageB",
...
}

In the calling object file, I have the following code setup:


if global constants is empty then
	set global constants to (:)
end if

...

add properties of (value of file "/Users/Account/Documents/TestSuite.suite/Scripts/ImageValues.script") to global constants

Am I pointing to an invalid script? Should I not incldue the .script at the end of the script name? Should I not be using the FQN of the file?

At this point, I’m lost. :?

I really do appreciate the help though!!

You might want to try displaying the value of the constants global right before your “add properties” command. Either insert a “put global constants” command there, or better yet a “pauseScript” command so you can type some put commands in the Do box to examine the values of various things.

If the global constants is not a property list at that point (type “put global constants is a property list” in the Do box and it will respond with true or false), then you’ll need to track through your earlier code to see why it isn’t.

You can also examine the contents of your data file. SenseTalk lets you treat a file just like a variable: the expression “file filename” refers to the contents of the file. Filename should either be the full path to the file or else a relative path from the current folder (“the folder”).

As to what to call your data file, I wouldn’t give it a name ending in “.script” since it’s not a script, and I probably wouldn’t put it in the Scripts folder either. For data files in a suite, we suggest creating a Data subfolder in the suite (alongside the Scripts, Images and Results folders) and keeping those files there.

For tracking down your problem, I strongly suggest using Eggplant’s debugging capabilities to step through the relevant parts of your script a line at a time. Use the Do box at the bottom of the Run window to enter put commands to display the value of any variable or expression, or to execute any command directly – whatever you type is executed “live” within the context of the script when it’s paused, so it’s a great way to explore exactly what’s going on.

I was able to find a work around.

I formatted the Data files as follows:

to initialize
  add the properties of this object to me
end initialize

Properties
   valueX: "Something",
   ....
End Properties

Later on, when I want to load the values into a global array,


put a new DataFile into variable -- DataFile is name of file
add the properties of variable to global constants

In this way I was able to get the values loaded into the global array.