passing data to functions and subs

Since I didn’t completely understand many things about BrightScript programming when I started my app, I built it out of in-line code, all in the main() sub. Now that I’ve got an almost working prototype, I want to start organizing it into functions and subs.

some questions for the experienced:

  1. The manual says there are no Global variables. So lets say I have

port = CreateObject(“roMessagePort”)
audioPlayer.SetMessagePort(port)

in main().

Now I have a function or sub in which I want to set some other object to send messages to that port. If port is not a global variable, how does it work to

call poster.SetMessagePort(port) in a function or sub?

  1. What logic would I use to determine if I want to use a function vs a sub for a given piece of code?

“jbrave” wrote:
Since I didn’t completely understand many things about BrightScript programming when I started my app, I built it out of in-line code, all in the main() sub. Now that I’ve got an almost working prototype, I want to start organizing it into functions and subs.

some questions for the experienced:

  1. The manual says there are no Global variables. So lets say I have

port = CreateObject(“roMessagePort”)
audioPlayer.SetMessagePort(port)

in main().

Now I have a function or sub in which I want to set some other object to send messages to that port. If port is not a global variable, how does it work to

call poster.SetMessagePort(port) in a function or sub?
There is a global “m.” instance that you can stuff data in. I don’t know how others do it, but in my code, I create a “Configuration” object that stores all of the data I need to use globally, then I stick that in m.Configuration in the RunUserInterface/Main function.

“jbrave” wrote:
2. What logic would I use to determine if I want to use a function vs a sub for a given piece of code?
A Function returns a value, whereas a Sub does not.

can you do this:

port = CreateObject(“roMessagePort”)
m.portref=port
poster = CreateObject(“roPosterScreen”)
m.poster=poster

and then:

sub test()
poster=m.poster
poster.SetMessagePort(m.port)

or

sub test()
port=m.port
poster=m.poster
poster.setmessageport(port)

You can, or you can simplify it further and directly set the m. variable:

Sub Main()
    m.Port = CreateObject("roMessagePort")
    Test()
End Sub

Sub Test()
    poster = CreateObject("roPosterScreen")
    poster.SetMessagePort(m.Port)
    ' do my other stuff
End Sub

awesome. I really am trying to figure this out myself, but I keep coming up against things that are not clear enough in the documentation for me to easily understand. Hopefully all these posts and discussions will help others who want to learn the ins and outs of this system.

The “m” variable serves dual purposes, to be a global variable access point for vanilla functions, and to work as the object pointer, commonly “this” or “self” in other languages, when the function is called as a method on an object. It’s very similar to javascript, if you are familiar with that.

E.g.


function printCoords()
    coord_x = m.x
    coord_y = m.y
    print "Coordinate is ("; x; ","; y; ")"
end function

point = {
    x: 10
    y: 13
    print: printCoords ' Note the lack of parenthesis
}

print.print() ' prints "Coordinate is ( 10, 13)"

Generally I make a function to do the work of creating the object, such as


function newPoint(coord_x, coord_y) as object
    this = {
        ' Member vars
        x:coord_x
        y:coord_y
        ' Member funcs
        print: function() : print "Coordinate is ("; m.x; ","; m.y; ")" : end function
        return this
    }
end function

p1 = newPoint(1,2)
p2 = newPoint(10,-123)
p1.pint()
p2.print()

In all these cases, “m” is not global, but refers to the associative array that the function was called from. If the same function was called by itself, m would be global.

“kbenson” wrote:
The “m” variable serves dual purposes…and to work as the object pointer, commonly “this” or “self” in other languages, when the function is called as a method on an object. It’s very similar to javascript, if you are familiar with that.

In all these cases, “m” is not global, but refers to the associative array that the function was called from. If the same function was called by itself, m would be global.

Well the code you posted is readable, but I really don’t understand what you mean, or what the manual means by “this” or “self”.

Also when you say “function is called as a method on an object” I think that means object.CallFunction() right, like msg.GetIndex() ?

  • Joel

“jbrave” wrote:

Well the code you posted is readable, but I really don’t understand what you mean, or what the manual means by “this” or “self”.

It’s really an Object Oriented programming technique. It can make management and control flow easier for some problems, but really it’s all a matter of what you’re used to and how you think.

In many other languages that support OO programming, a special variable, generally called “this” or “self” is present in methods of an object, and it refers to the current instantiated object. In my previous example, the print method uses the “m” variable to access m.x and m.y. These are the values of the instance of the object. That is, they refer to the associative array entries for that specific object. They are different when called as p1.print() and p2.print(). It’s just a convention of the language that “m” refers to the base associative array for the object.

You’ve seen the point class example above, the classic procedural programming style for that might be something like this:


function point_new(px, py) as object
    point = { x:px, y:py }
end function

function point_print(point)
    print "Coordinate is "; point.x; ","; point.y; ")"
end function

p1 = point_new(1,2)
point_print(p1)

The benefits of OO programming can be manifold, but so are the drawbacks. I prefer it for many instances because it helps encapsulate all the behavior in a single area, so it’s obvious where to look if I want to change or add to how points behave or what they can do. You also don’t have to worry about namespace conflicts as much.

Also when you say “function is called as a method on an object” I think that means object.CallFunction() right, like msg.GetIndex() ?

Sort of. :wink: the built-in types are using “interfaces”, not methods as they are used in any other respect in the language. Usually it means no difference when coding, but there’s specific things you can’t do with them (like assign them to variable or as a method on an actual object). Really, all the components and built in types are implemented in C or C++ for speed, and don’t interrelate in some ways like purely interpreted code.

It all becomes easier to conceptualize when you’ve used a language where the sugar on top of objects is a thin veneer at best. E.g. Perl, javascript, brightscript, etc.

Sorry if I sort of hijacked the thread. All this OO stuff wasn’t actually your original question, I just wanted to clarify what “m” is for in case you saw it elsewhere and were confused.

Hey, no problem, I appreciate your attempts to help me. Feel free to chime in on any questions I ask, I’m going to have more in the days ahead, I’m really working hard on an app, but I don’t just want to “get it done” I want to understand what I’m doing. If I was doing this for a living, I would have to sacrifice learning for time critical problem solving. Mostly I worry that I’m going to annoy people by asking so many questions, hopefully not.

  • Joel

“jbrave” wrote:
I’m really working hard on an app, but I don’t just want to “get it done” I want to understand what I’m doing. Mostly I worry that I’m going to annoy people by asking so many questions, hopefully not.

We like it when people want to actually understand, rather than just be spoon-fed finished code. Don’t worry, honest desire to learn isn’t annoying unless you’re unwilling to crack a manual – and I’ve seen no evidence of that yet. :slightly_smiling_face:

Thanks G+K!

One more question on the m. thing:

is there any reason not to use m. for all my variables? Seems like it will simplify everything for me to just prefix and relate to all variables arrays etc with m. Will that bite me later on?

  • Joel

I wouldn’t “always” use m. in front of all your variables… You just need to be aware of the context of your variables.

  1. In the global scope: The default “object” scope for all methods not explicitly in any other object scope
  2. Within an object, or an associative array, “m.” refers to names within the associative array of the object
  3. Local variables within a function do not have an m. or another object name qualifier in front of the name
  4. Parameters to functions do not have an “m.” in front of the name.

–Kevin