Problem with adding helpers to an object dynamically

*Using Version 10.2 (1763) on OSX*
Hi,

i try to insert and remove helpers to an object at runtime. first, i assign one helper to an object, this helper is always used.

helpers of the object before inserting a new helper
put the helpers of oParser
(/Users/KLTA/Documents/TestAction.suite/Scripts/Global/Common/Parser.script)

after inserting:
insert oRun into the helpers of oParser
put the helpers of oParser
(/Users/KLTA/Documents/TestAction.suite/Scripts/Global/Common/Parser.script,Object <2d9c2a40>)

ok, so i assume that "Object<>" is the object oRun i inserted. i tried to call a function which does not exist in my Parser.script and the function was called in the helper object oRun, so it works.

BUT:
now i try to dynamically insert and remove helpers from the oParser object with the only difference, that i am inside the Parser.script (so "me" is the Parser.script)
		delete oPlatform from the helpers of me
		put new platformScript into oPlatform
		insert oPlatform into the helpers of me

		delete oProject from the helpers of me
		put new projectScript into oProject
		insert oProject into the helpers of me

after this lines i would think, that two new objects were inserted as helpers but
put the helpers of me
(/Users/KLTA/Documents/TestAction.suite/Scripts/Global/Common/Parser.script,Object <2d9c2a40>)

eggPlant only shows only the first inserted helper "oRun".

Could you please tell if i am wrong and this works as designed or if its a problem within eggplant?

thx in advance

Comments

  • SenseTalkDougSenseTalkDoug ForumAdmin admin
    I tried to recreate your situation here and was successful in adding other helpers, so I'm not entirely sure what is going wrong for you. Your insert commands look correct, although the delete commands are not (which I'll explain in a moment). Here is my code which works fine in Eggplant 10.2 on a Mac:
    (* Master.script *)
    insert Helper1 into my helpers
    put my helpers
    init
    put my helpers
    foo
    
    Helper1 looks like this:
    (* Helper1.script *)
    to init
      put "Helper1 init"
      insert Helper2 into my helpers
    end init
    
    Helper2 looks like this:
    (* Helper2.script *)
    to foo
      put "Foo!"
    end foo
    
    Running the Master script gives this output:

    (/Users/doug/Documents/EggplantSuites/DynamicHelpers.suite/Scripts/Helper1.script)
    Helper1 init
    (/Users/doug/Documents/EggplantSuites/DynamicHelpers.suite/Scripts/Helper1.script, /Users/doug/Documents/EggplantSuites/DynamicHelpers.suite/Scripts/Helper2.script)
    Foo!

    Some of the objects you're using as helpers are in-memory objects that display as "Object <...>". That should work fine, too, but there are some subtle points to be aware of.

    Inserting Helpers
    When you insert an object into the helpers list, SenseTalk makes a copy of that object and inserts the copy. You can see that here:
    set obj to (x:1)
    put long id of obj
    insert obj into my helpers
    put my helpers
    set script of obj to {{
    to foo
      put "Foo!"
    end foo
    }}
    
    foo
    
    Running this script gives this result:

    Object <97e4e10>
    (Object <97e6210>)
    Fri, 8/20/10 4:09:39 PM FAILURE STUnknownMessage ERROR: No Such Command: 'foo'

    You can see that the helpers list contains a different object than the original 'obj', and since the script of obj was set AFTER inserting it into my helpers, the call to foo fails.

    You can overcome this problem by inserting a reference to the object, like this:
    set obj to (x:1)
    put long id of obj
    insert reference to obj into my helpers
    put my helpers
    set script of obj to {{
    to foo
      put "Foo!"
    end foo
    }}
    
    foo
    
    Now, running the script gives the desired result:

    Object <97cf850>
    (Object <97cf850>)
    Foo!

    Deleting Helpers
    To delete an object from the helpers list, the simplest approach that will work is to delete the item by number. If the helper you want to remove is the last one that was added, you can simply say:
    delete the last item of my helpers
    
    Otherwise, to delete a particular object from the list you'll need to get its item number in the list:
    set helperNum to the item number of obj within my helpers
    delete item helperNum of my helpers
    
    The delete ... from ... command was designed to delete occurrences of text from a container. So it won't currently work properly to delete an item from a list.

    I hope this information is enough for you to resolve your problem. If not, please post more details about exactly what you're doing and we'll take another look. There were some bug fixes in 10.2 that might have an impact on this (and which haven't been released on all platforms yet), so if you're using an earlier version it may work somewhat differently.
  • First, thank you for the detailed explanations, they bring a little light into the darkness of eggPlant objects :wink:

    But since i can not solve the problem with the tips from your post, i have attached a very small suite, which does the same as my real suite. please start the "Start" script and you will see, that the helper objects were not added to the helper list. maybe you find the problem and can tell me, what i am doing wrong!
  • SenseTalkDougSenseTalkDoug ForumAdmin admin
    Thank you for the sample code you posted! That allowed me to immediately reproduce the problem. It took a bit longer to track down exactly what's going on. ;) The root of the problem turns out to be a previously-undetected bug that prevents assigning two (or more) objects that look alike as helpers of an object. The intent was to prevent the same object from being added to a helper list more than once, but the implementation excludes any objects with the same properties as another helper in the list.

    Fortunately, there is a workaround that you can use: just assign a unique property value to any object that will be used as a helper. I suggest the following approach which worked well in my tests:
    set oRun's uniqueID to the long id of oRun -- assign a unique property value
    insert a reference to oRun into the helpers of oParser
    
    The first line here assigns a uniqueID property to the oRun object before it is added to oParser's helpers. To ensure oRun's uniqueness, I set the value of the id to the long id identifier for that object. Another idea would be to use the current time as the value. Anything will work as long as the various helpers have different values.

    This is a little extra work which shouldn't be necessary, of course. But it will get your script working until this bug is fixed, which should be in the next release of Eggplant. Thanks again for your clear reporting of this issue!
  • ahhh perfect, the little extra work should be no problem for now.

    if i remember correctly, there is something like a constructor function which is called when an object is created. if this is right, i could implement this unique id behaviour inside this function.

    thank you
  • SenseTalkDougSenseTalkDoug ForumAdmin admin
    Yes, each newly-created object is sent an initialize message, so just adding something like this handler to each of your prototype script objects would provide a neat solution:
    to initialize
    	set my uniqueID to the long id of me
    end initialize
    
Sign In or Register to comment.