Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
MarkRoddy
Level 7

dot operator behavior question

I've been using the 'dot' operator for some "classes" I'm using, but I'm hitting a road block when trying to build a dynamic dispatch table.

To give an example of what I need to accomplish consider the following function. Effectively, it returns the attribute specified if the 'm' variable is assigned as expected when the function return attr is called using the '.' operator or a string stating that the attribute does not exist:
Function returnattr(attrname as String) as Object                                                                 
if not m.DoesExist(attrname) then
return "Attribute " + attrname + " does not exist"
else
return m.Lookup(attrname)
end if
End Function


Now consider the following scenarios:
Sub test_dynamic_dispatch(t as object)                                                                            
obj = CreateObject("roAssociativeArray")
obj["getattr"] = returnattr
obj["a"] = "a"

'Using dot operator to perform call
t.assertEqual("a", obj.getattr("a"))

'Using dot operater in an eval()
result = "NO VALUE ASSIGNED"
attrname = "a"
code_snippet = "result = obj.getattr(attrname)"
eval(code_snippet)
t.assertEqual("a", result)

'Using dot operator to do method dispatch
method = obj.getattr
t.assertEqual("a", method("a"))
End Sub


The first (explicitly using the dot operator) and second (using eval) approaches work as expected. In the case of the third (looking up the method then calling it) the 'm' variable is assigned to an empty roAssociativeArray. Is to be expected that the only time 'm' will be set is when the method is explicitly called with the dot operator even if the method is accessed with the dot operator initially?

-Mark
0 Kudos
14 Replies
Highlighted
RokuKevin
Level 9

Re: dot operator behavior question

Mark,

Yes, the current behavior is that the only time 'm' will be set is when the method is explicitly called with the dot operator. I suggest not relying on this behavior in any of your code, as we will continue to expand BrightScript's capabilities in the future. Including dynamic dispatch, closures, etc... could reasonably make the cut at some point.

Your eval() technique above is probably a reasonable work-around for the time being in scenarios like unit-test frameworks.

--Kevin
0 Kudos
Highlighted
MarkRoddy
Level 7

Re: dot operator behavior question

"RokuKevin" wrote:
Mark,

Yes, the current behavior is that the only time 'm' will be set is when the method is explicitly called with the dot operator. I suggest not relying on this behavior in any of your code, as we will continue to expand BrightScript's capabilities in the future. Including dynamic dispatch, closures, etc... could reasonably make the cut at some point.

Your eval() technique above is probably a reasonable work-around for the time being in scenarios like unit-test frameworks.

--Kevin


Kevin,
Thanks for the response. I've started using the eval() technique for the time being.

When you say not to rely on the behavior do you mean the dot operator/'m' variable in general (as I'm using it quite a bit currently)? Or do you mean the distinction of when the 'm' variable is set or not?

Also, I'm VERY happy to hear that there's a possibility to include closures. I was disappointed when I realized the first time I used anoymous function to find that I couldn't close over variables in the containing scope.

-Mark
0 Kudos
Highlighted
RokuKevin
Level 9

Re: dot operator behavior question

Mark,

You can count on the 'm' variable to be set when the method is explicitly called with the dot operator.

I meant don't count on the distinction of when the 'm' variable is set or not....

--Kevin
0 Kudos
Highlighted
MarkRoddy
Level 7

Re: dot operator behavior question

"RokuKevin" wrote:
Mark,

You can count on the 'm' variable to be set when the method is explicitly called with the dot operator.

I meant don't count on the distinction of when the 'm' variable is set or not....

--Kevin


Kevin,
Thanks for the clarification.

-Mark
0 Kudos
Highlighted
MarkRoddy
Level 7

Re: dot operator behavior question

Kevin,
Just an FYI, the approach of using eval() discussed here was how I attempted to implement a dispatch table, but unfortunately it does not seem to be working in my case due to what appears to be a bug causing the DVP to crash when used recursively (something I need to do for my use case). The following code reproduces the issue:

Sub Main()                                                                                                        
result = SomeFunction(100)
End Sub

Function SomeFunction(x as integer) as integer
if x = 0 then
return 0
else
x = x -1
result = -1
eval("result = SomeFunction(x)")
return result
end if
End Function


In the case of the dispatch table I implemented this would cause crashes non-deterministically so I'm not entirely sure where the issue is. I can only guess it has to do with using eval() from within the context of another eval() call. For the time being I've switched to using an ugly if/else if/else if/..../else statement.

-Mark
0 Kudos
Highlighted
RokuKevin
Level 9

Re: dot operator behavior question

Mark,

Thanks for the crash report. I've opened a bug for it.

Kevin
0 Kudos
Highlighted
RokuAnthony
Level 7

Re: dot operator behavior question

eval() performs a compile, so it is slower than you might expect.
0 Kudos
Highlighted
MarkRoddy
Level 7

Re: dot operator behavior question

"RokuAnthony" wrote:
eval() performs a compile, so it is slower than you might expect.


Thanks Anthony. Unfortunately, there are several pieces of dynamic functionality I need that currently can only be implemented via calling eval(). On the up side, 'slow' is not as much of an issue for the testing framework I'm working on, especially considering there is no UI (at this point).

-Mark
0 Kudos
Highlighted
kbenson
Level 7

Re: dot operator behavior question

FYI, I think (and my testing shows) there IS a way to handle this without eval. Use the alternate AssociativeArray syntax (square brackets).


function testclass() as object
this = {
foo: "bar"
func: function() as boolean
print "in method, foo is "; m.foo
for each attr in m
print " found "+attr+" in m"
end for
end function
}
return this
end function

sub main()
c=testclass()
c.func()
c["func"]()
end sub


You get this output, which implies c.func() and c["func"]() result in the same behavior.

in method, foo is bar
found func in m
found foo in m
in method, foo is bar
found func in m
found foo in m


That seems to imply it's not really the dot operator, but the associative array existence that sets m. I don't know whether this was changed since this was mentioned here, just noting how I see it working currently.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos