Procedural Programming in REALbasic


REALbasic is an object-oriented programming language, but as I said earlier, REALbasic takes a practical approach to object-oriented programming and retains procedural programming elements. In this section, I will start with the language elements of REALbasic that are more procedural and will defer until the next chapter a discussion of REALbasic's object-oriented features.

Statements and Declarations and Comments

A method is made up of a series of declarations, expressions, and statements that make up your application's programming code. These serve as the building blocks for functions and subroutines, and this is where we will start in our review of the REALbasic programming language. Throughout this section I will use snippets of code to serve as examples. One thing you will see quite often are comments that I include in the sample code to explain what's happening at a particular point or to let you know what the value of a particular variable should be. A comment is some text included by the programmer that is ignored by the program and intended to document a portion of code. A comment in REALbasic can take on one of two forms:

'A line starting with an apostrophe is a comment // As is a line starting with two forward slashes 


When writing any kind of program, it's a good idea to make liberal use of comments throughout your code. This will help you (or someone else in the future) understand what your code is doing.

Expressions: Operands and Operators

Operators and functions are related to each other. In fact, in mathematics an operator is a kind of function. The technical definition of a function is that it takes an input and returns an output according to a set of rules. In computer programming, the definitions of both functions and operators are a little more squishy, but it helps to understand their mathematical heritage.

Operators are used in expressions. An expression is a combination of one or more operands, plus one or more operators that are used to calculate a new value.

Here is an example of an expression:

2 + 2


In this example, the operator is the plus sign (+) and the operands are both 2. You should be able to see that the answer to this equation is 4. The number 4 is the value returned by this particular expression.

Like a function, you can think of the operands that make up an expression as the inputs to a function. The operators are the rules that tell the computer how to calculate the new value based on the input given.

The REALbasic programming language has a variety of operators. You will likely be familiar with most of them already, including +, -, *, /, and ^ for addition, subtraction, multiplication, division, and power, respectively. There are two others, mod and integer division (\), which I will discuss shortly.

Variables and Literals

There are two ways represent the operands of an expression in REALbasic. When I write

2 + 2


I am using what is called a literal. In this case, the literal value for the integer is 2. (In these examples, all the literals I am using are numbers, but you can use characters, too, as long as you use quotes around them. See the section titled "Strings" later on in this chapter for more information.)

If I wanted to solve the preceding expression on a piece of paper, I would write it out like this:

2 + 2 = 4


However, I can't do this when writing a program, because I presumably do not know the answer to the expression prior to having the program calculate the answer (why else would I express it as an expression?). When you use an expression in programming, you are making a calculation and you need to find a place to store the value that is returned from the expression.

In this example, we need to figure out what to do with the answer to the expression 2+2. You do this by declaring a variable, which is a letter or sequence of characters that represent a value of some sort. When I declare a variable, I have to declare what type of variable it is. In this case, the number 2 is an integer, so I will declare the variable as the intrinsic data type integer. In REALbasic, data types are declared using the Dim statement.

Dim a as Integer a = 2 + 2


In programming terms, this is known as an assignment. I am assigning the result (or answer) from the expression to the variable a. Assignment doesn't work exclusively with expressions. For example, you can assign the value of one variable to that of another variable.

Dim a as Integer Dim b as Integer a = 2 + 2 b = a 


Now, both the variable a and the variable b represent the value 4. You can also do something like this:

Dim a as Integer Dim b as Integer Dim c as Integer a = 2 + 2 // a = 4 b = 3 - 1 // b = 2 c = a + b // a + b = 6 


There is potential for confusion, however. Consider the following:

Dim a as Integer Dim b as Integer Dim c as Integer Dim d as Integer a = 2 // a = 2 b = 2 + 3 - 1 // b = 4 c = a * b // c = 8 d = 2*2+3-1 // d = 6 


Why is the answer for c equal to 8, whereas the answer for d is equal to 6, when it looks like they used the same numbers? The reason is that the expression used to calculate the value for d calculates the answer in a slightly different order than that used by c. For c, 2+3-1 is calculated first, giving an answer of 4. Then, the value of a is multiplied by 4, giving the answer 8. When d was calculated, 2*2 was calculated first, giving the answer of 4. Then, 4 was added to 3, giving an answer of 7. Finally, 1 is subtracted from 7, leaving an answer of 6.

The order in which operands are calculated is determined by the operators and the order of precedence. Basically, things are multiplied first, then divided, then added, and then subtracted. If you want to have control over the order this happens, you can use parentheses. To get the expression used to calculate d to arrive at the same answer as that given for c, you would write it this way:

d = 2*(2+3-1)


The parentheses tells the program to calculate 2+3-1 first, and then multiply the answer by 2.

Expressions are used in a few ways when writing a software application, but I think the most common is to use an expression to assign a value to a variable of a given type. There are also cases when an expression can replace a literal or a variable when used as a parameter passed to a method.

Intrinsic Data Types

When we looked at expressions, we saw that they were composed of operators and operands. I said that operands could be either literals or variables and that if you used a variable for the operand, you would have to first declare the type of the variable before you used it.

REALbasic is a statically typed programming language. This means that every variable has to be declared before it can be used. Some programming languages, especially those used for scripting, are dynamically typed. In those languages you can refer to variables that you have not declared and the type that variable represents isn't determined until the program is running.

If you are a Visual Basic programmer, REALbasic behaves like Visual Basic does when OPTION EXPLICIT has been set.

The following table lists the intrinsic data types available in REALbasic, along with information about the range of values each can hold.

Table 2.1. Data Types

Data Type

Range of Values

Boolean

True/False

Integer

Values between plus/minus 2,147,483,648 (4 bytes)

Single

Real number, with a decimal value, -1.175494 e-38 to 3.402823 e+38 (4 bytes)

Double

Sometimes called double precision real number, a value between 2.2250738585072013 e-308 and 1.7976931348623157 e+308 (8 bytes)

String

A string of character values, encoded in UTF-8

Color

(3 bytes)


Declaration

To use a variable in your program, you must first declare the variable. In REALbasic, you can declare a variable with the Dim statement (short for Dimension). When you declare a variable, you are telling REALbasic to set aside memory for it and what kind of information the variable represents.

For example:

Dim i as Integer Dim s as String 


If you have several variables to declare, REALbasic also lets you declare them all at once, as long as they are of the same type:

Dim a,b,c,d as Integer 


Data types are important because they tell REALbasic how to interpret the value of any data stored at a particular address. All a computer knows about are numbers and at the lowest levels, the computer only knows about two numbers: 0 and 1.

For example, suppose you've declared a variable and set the value to 97. How your program will interpret the number 97 is entirely dependent on what data type the variable is. If the data type is an integer, it will treat the value as an integer. If the data type is a string, it will treat the value as the lowercase letter a.

Dim is also not the only way to declare or use variables. There are some cases where you declare the use of variables (or variable-like constants) using REALbasic's graphical user interface. In other words, when you create a module and establish properties for that module, you are effectively declaring variables, even though you are not using the Dim statement.

Variables and Constants

Behind the scenes, a variable represents an address where a value is stored in memory. It's kind of like the sales clerk at the convenience store down the street. Every morning I get up and drive down to the same street address to get a cup of coffee, but every day there's someone new behind the counter. Same address, different person.

When you create a variable, you are telling REALbasic to use the value that is stored at that particular address. If you know the value is never going to change for the duration of the variable's lifespan, then you can declare it as a constant. Unlike the convenience store example, a constant means that every time you go to a given address, you'll find the same person. Same address, same person. I suppose that makes a constant more like a tombstone or the nightly news.

The primary reason or justification for making the differentiation between variables and constants is that your program can handle constants more efficiently than it handles variables.

Scope

Variables and constants always have a certain scope. Scope refers to when and how a variable or property can be accessed and the lifetime of that variable or property.

Local Variables and Constants

Sometimes you need to use a variable inside a method as a temporary container of information. In this case, that variable is meaningful only within that method. As soon as the method is finished executing, the variable is discarded. These are usually referred to as local variables. There can also be local constants, declared and used within a method, and the same rules apply.

Global Variables (Module Properties) and Module Constants

Variables that are associated with a module are called properties (in other programming languages, they would be called global variables), and properties of a module exist as long as the module exists. Part of what makes a module a module is that it exists in memory and is accessible whenever your program is running. As you will see in the following chapters, this is not the case with classes.

A variable's scope can be further narrowed by specifying whether it is Public, Protected, or Private, which sets limits on which objects can have access to the property (methods have scope, too).

Public means that any other object can call the method or access the property. Protected means that only objects that share the same class as the object to whom this property is associated can access it. Private means it's restricted exclusively to the object itself, and subclasses cannot access it directly.

Scalar Variables and Reference Variables

There are two types of variables: scalar and object. A scalar variable represent a particular value or a certain type. REALbasic has a set of intrinsic data types that you will use when declaring scalar variables.

For the time being, I will be discussing only scalar variables. A reference variable is a reference to an object, and references work differently from scalar variables. When dealing with scalar variables, there are two things we need to know. The first is the value the variable represents and the second is the data type of the variable.

In the IDE, modules use the same basic terminology as classes do. Modules have properties, methods, and constants. It's important to understand that a module property really isn't the same name as a class property. When you create a class, the properties are associated with the class and serve as a descriptive value that is unique to any given class instance. Properties in modules are really more akin to global variables, and that is the way that you will use them.

Arithmetic with Integers, Singles, and Doubles

A computer is called a computer because it computes things. At a very basic level, computers can add, subtract, multiply, and divide numbers. The following section reviews REALbasic's approach to arithmetic.

Integer

In REALbasic, an integer requires 4 bytes of space to represent it. Recall that an integer is a whole number (no decimals), and it can be positive or negative in value. Because REALbasic uses 4 bytes of memory, that means the range of numbers an integer can represent is between plus or minus 2,147,483,648.

Singles and Doubles

Singles and doubles are floating-point numbers, which means they are numbers that can accept a decimal value. A Single uses four bytes; a Double uses eight.

A single can be within the range of 1.175494 e-38 and 3.402823 e+38. A single loses precision after about 6 decimal places.

A double can be within the range of 2.2250738585072013 e-308 and 1.7976931348623157 e+308. A double loses precision about 16 decimal places.

Number Literals

Even though you do not have to declare a literal, a literal still has a type, which REALbasic deduces for you. For example:

Dim i As Integer i = 3/1.5 //i=2 


Because you declared i as an integer, REALbasic knows it's an integer, but what about the literals 3 and 1.5? REALbasic knows what they are, too. 3 is an integer and 1.5 is a floating-point number (either a short or a double).

Coercion

Using data types properly can be tricky and can lead to unforeseen problems if you do not handle them correctly. The problems come into play when using operators with values of different types, so it's important to understand that even literals have types.

Here's a simple example of mixing data types:

Dim i as Integer Dim d as Double d = 1.8 i = d // i = 1 


In this example, i is declared as an integer, whereas d is declared as a double. Because integers by definition don't have decimal points, REALbasic drops everything after the decimal point. This is called coercion or typecasting. Note that it doesn't round up to the nearest value or anything like that. It just chops it off as if it never existed. You can try the same thing using literals and get the same results:

Dim i as Integer i = 1.8 // i = 1 


Because i is an integer and 1.8 is not an integer, everything to the right of the decimal point is dropped again. The floating-point value 1.8 is being "coerced" into being an integer.

Another situation exists when you perform a calculation on two operands of one type whose answer is of a different type. Consider the following:

Dim m as Integer Dim n as Single m = 3/2 // m = 1 n = 3/2 // n = 1.5 


In this case, the integer 3 is divided by the integer 2, but the answer is 1.5, which is not an integer. When I assign the value of the expression to a variable that has been declared as an integer, the value is 1. However, if I assign the value to a single or a double, as I did with the variable n, the correct answer appears.

Because I've already told you that if you assign a single or double literal to an integer, REALbasic just drops everything to the right of the decimal point when assigning the value to the integer, you might find this example a little confusing:

Dim m as Integer Dim n as Double Dim o as Integer m = 3/1.4 // m = 2 n = 3/1.4 // n = 2.142857 


You might be tempted to assume that REALbasic drops the .4 from 1.4 and then divides 3 by 1, but that would give you an answer of 3 instead of 2, and that's clearly not happening because the answer is 2. Instead, REALbasic calculates the answer as a double, and then it drops off everything to the right of the decimal when assigning the value to the integer variable m. In this example, it gets the answer of 2.142857 and then assigns the value of two to the variable m. In other words, it does not drop the decimal values until after it calculates the expression.

As it happens, another operator that is used for integer division converts the values of the operands to integer prior to performing the division. The operator is \ and you can see how it leads to a different answer in the following example:

Dim m as Integer o = 3\1.4 // o = 3 


The value for o is 3 because 1.4 is cast to an integer prior to dividing it into 3.

Another potential problem arises when you try set the value of an integer to a number that is outside the legal range for an integer. Remember that an integer can be a number in between plus or minus 2,147,483,648. One important thing to understand is that between means between. In other words, a legal value for an integer is greater than -2,147,483,648 and less than 2,147,483,648. It cannot be equal to -2,147,483,648 or 2,147,483,648

In this example, everything happens as expected:

Dim d as Double d = 2147483647.0 + 1 // d = 2,147,483,648 


Now look at what happens if you assign the value to an integer:

Dim i as Integer i = 2147483647.0 + 1 // i = -2,147,483,648 


When you assign the value to a double, the answer is positive, but when you assign it to an integer, the answer is negative. What? The reason is that when you assign a number to an integer which is outside the legal range, it simply starts over again and starts counting from the lowest boundary. Here's what happens as the number assigned to the integer gets higher:

Dim i as Integer i = 2147483647.0 + 1 // i = -2,147,483,648 i = i + 1 // i = -2,147,483,647 i = i + 1 // i = -2,147,483,646 i = i + 1 // i = -2,147,483,645 


As you can see, it is now counting up from the lower bounds of the range. Interestingly enough, this doesn't happen when assigning a value to a single that is out of range. The single ignores the higher values, treating anything above the legal range as infinity (Inf). For example:

Dim s as Single Dim s2 as Single Dim d as Double s = 3.402823e+38 // s = 3.402823e+38 s2 = 3.402823e+39 //     s2 = inf d =  3.402823e+39 // d = 3.402823e+39 


Anything out of range for a single returns Inf, for infinity. Recall that anything multiplied by infinity equals infinity, and that's just how the value works. If you assign the same value to a double, you get a double back, which means that the same literal (in this case 3.402823e+39) will be treated as infinity if the variable is a single, but as the proper value if the variable is a double. If you assign a number to a double outside of a double's range, it will also return infinity.

Floating point numbers are also not as accurate as an integer. For example, if you were to examine the decimal value of s from the previous example, you would get the following digits:

340,282,306,073,709,652,000,000,000,000,000,000,000 


Mod Operator

Mod returns the remainder derived as a result of the division of two integers. The most common use of Mod is to determine whether a number is an even or an odd number. Because anything divided by two is considered an even number, all you need to do to check for this is the following:

Dim aNumber, result as Integer result = aNumber Mod 2


Note that Mod operates only on integers. If either of the two values used with Mod are floating-point numbers, they are cast as integers, which means everything to the right of the decimal point is dropped.

Boolean and Comparison Operators

In addition to arithmetic operators, REALbasic also provides a number of operators to be used when comparing values.

=, <, <=, >, >=, <> 


These are the familiar equal, less than, less than or equal to, greater than, greater than or equal to, and not equal to operators from your grade school arithmetic. When you compare two things and ask whether they are equal, or if one is greater than the other one, the answer you expect is either "Yes, they are equal," or "No, they're not." Whenever you need a yes or no answer, the data type to use is REALbasic's boolean.

Boolean

A variable that has been declared as a boolean can have one of two values: true or False. TRue and False are reserved words in REALbasic and you do not need to quote them when referring to them in your programming code. Here's an example of how you would declare a variable as a boolean and assign a value:

Dim b as Boolean b = True 


Comparison Operators

When using comparison operators, you can often get some constructs that look a little bit odd at first:

Dim b as Boolean Dim m as Integer Dim n as Integer m = 1 n = 1 b = (m = n) 


This is confusing because of the presence of two equal signs. Even though the same operator is being use in two different places, they are being used in two entirely different ways. This is the first example of operator overloading I've addressed in the book. Overloading is an important concept in object-oriented programming. It means that you do two or more different things with the operator depending on the context. The context is determined by the values (or operands) that are provided. Later in this section you will see how to do your own customized operator overloading.

In the previous example, REALbasic handles the expression in parentheses first. Because both m and n are integers, REALbasic treats this as the equal comparison operator and tests to see if the value for m is the same as the value for n. In this example, the values are, in fact, the same, so the Boolean value True is returned. The equal sign that comes right after b is the assignment operator, and it is used to apply the value from the right side of the operator to the variable on the left side. REALbasic is often smart enough to figure this out without any help from parentheses, but it's always a good idea to use them because it avoids ambiguity, both to the REALbasic compiler and to any human beings who may happen upon your code at some future date.

You use the other comparison operators the same way:

Dim b as Boolean b = (4<5) // true b = (4<4)  // false b = (4<=4) // true 


You can also mix and match expressions, but you still have to pay attention to operator precedence:

Dim b as Boolean Dim i as Integer b = 1<(1+4)*3-12 // true, 5 * 3 - 12 = 3 b = 1<1+4*3-12 // false, 1 + 12 - 12 = 1 


You cannot mix comparison operators, however, regardless of what you do.

Dim b as Boolean  b= 1<2<3 


This causes strange errors. In this case, the compiler raised an error that said it was expecting an integer. When I changed b to an integer, the error said that it was expecting a boolean. This was a pretty clear sign to me that the compiler had no idea what to do with it.

Boolean Operators

There are times, however, when you do need to make more than one comparison at the same time. Do not despair, for REALbasic has provided a solution, the boolean operators And, Or, and Not.

Boolean operators are used to compare boolean values. It's also the basis of boolean logic, which you use all the time, except you don't call it boolean logic. You might say to yourself, "If the department store has these jeans in my size and they are not too expensive, I'll buy them." Where's the Boolean logic? I'll rephrase the sentence in a way to make it more clear: "If it is true that the store has jeans in my size and if it is true that they are not too expensive, then it is true that I will buy them."

This kind of statement is also called a conditional because the truth of whether you will buy the jeans is based on the condition that the store has your size and that the jeans are not expensive. Now, for fun, let's turn this into some REALbasic code:

Dim mySize as Integer Dim myMoney as Double Dim storeSize as Integer Dim storePrice as Double Dim hasMySize as Boolean Dim isAffordable as Boolean Dim shouldPurchase as Boolean mySize = 38 storeSize = 38 myMoney = 49.50 StorePrice = 45.00 hasMySize = (mySize = storeSize) isAffordable = (storePrice <= myMoney) shouldPurchase = hasMySize And isAffordable // shouldPurchase = True 


In this rather long-winded example, I first compared my size with the store's size to see if they were equal. (I'm making the simplifying assumption that the store only has one size in stock.) After that, I checked to see if the price offered by the store was less than or equal to the amount of money that I had. I then used the boolean operator And to see if both hasMySize and isAffordable were True. Because they were both True, shouldPurchase is True as well.

That, by the way, is the definition of And. It takes a Boolean value on either side, and if both of those values are true, And returns TRue; otherwise, it returns False. Contrast And with Or, which returns true as long as only one of the values is TRue (but also if both are true).

Dim mySize as Integer Dim myMoney as Double Dim storeSize as Integer Dim storePrice as Double Dim hasMySize as Boolean Dim isAffordable as Boolean Dim shouldPurchase as Boolean mySize = 38 storeSize = 38 myMoney = 49.50 StorePrice = 45.00 hasMySize = (mySize = storeSize) isAffordable = (storePrice <= myMoney) shouldPurchase = hasMySize Or isAffordable // shouldPurchase = True 


The only difference in this example is the use of Or, but the answer is the same, TRue, because at least one of the operands is true.

In addition to And and Or, there is the Not operator, which returns the opposite of any boolean expression. If the value was true, it's now False. If it was False, it's now true. When you use Not, it's just like opposite day.

Dim b as Boolean b = Not(1<4) // b = False b = Not(1 > 4) // b = True 


Like everything else, it can be combined with other expressions, like so:

Dim b as Boolean Dim c as Boolean b = Not(1<4) Or (5=(10/2)) // True c = Not((1<4) Or (5=(10/2))) // False 


Do you see why b is true and c is False? The only difference is the additional parentheses in the second expression. In the first expression, 1 is less than 4, which is true. Not negates it, which makes the left side of Or evaluate to False. On the right side of the Or, 5 does equal 10 divided by 2. After both sides of the Or are evaluated, you have False Or true, which evaluates to true.

In the second expression used to assign a value to c, Not's negation is not applied until after the rest of the expression is evaluated. Because 1 is less than 4, the left side is true, and because 5 equals 10 divided by 2, the right side is true as well. Because TRue Or True returns true, the Not operator negates it and assigns False to c.

Strings

A string is a sequence of characters. Chances are you will be doing a lot of work with strings as you write your REALbasic applications. You've seen how operators work with numbers such as integers and doubles, but you may be surprised to find that operators work on strings, too.

The same arithmetic operators used with numbers work on strings, but in a way that makes sense for strings. So, if I have two strings, one holds the value "a" and the other holds the value "b", here's what happens when I add them together:

Dim a,b,c as String a = "a" b = "b" c = a + b 


When I add two strings together, they are concatenated, which is a fancy way of saying they are joined together. In this case, c now equals ab. Now, let's try something else out:

Dim a,b,c as String a = "1" b = "2" c = a + b 


In this example, a and b are both strings, but they refer to the character "1" and the character "2". Because the variables are of the data type string, REALbasic treats it just like any other string and assigns c the value of 12.

Joining strings with the + operator is convenient, but consider yourself warned: it's a VERY slow operation, and there are many cases when there are other approaches for joining strings that are more effective (see the section "Arrays").

You can also use comparison operators on strings as well.

When you compare strings, the comparisons are not case sensitive.

Dim s, t as String Dim b,c as Boolean s = "Dog" t = "dog" b = (s = t) // b is True c = (s <> t) // c is False 


Strings can also be empty. You can assign an empty string to a string variable, like so:

a = "" 


You can test for an empty string by saying:

Dim b as Boolean Dim a as String a = "a string" b = (a <> "") // b is True 


In addition to these operators, REALbasic provides a group of built-in functions that are used with strings. These are reviewed later on in this section.

Color

Colors are represented in REALbasic by a data type that takes up three bytes, one byte each for the colors red, green, and blue. There is a special literal format for colors, which uses hexadecimal numbers to represent each of the three colors. In decimal terms, each value ranges from 0 to 255, which is 00 to FF in hexadecimal notation. This is similar to the way that colors are represented in HTML. Here's an example that shows the literal value for the color black and the color white:

&c000000 // black &cFFFFFF // white 


Literals

There is more than one way to express a number as a literal. You can also write numbers in binary, hexadecimal, and octal format. The next example shows how to represent the value 65 in hexadecimal, octal, or binary format:

Dim x,y,z as Integers x = &h41 y = &o101 z = &b1000001 // x,y and z all equal 65 


Visual Basic Data Types

If you are porting from Visual Basic to REALbasic, you will have noticed that REALbasic has a smaller set of Data types than Visual Basic does. However, because of REALbasic's object orientation, there are usually different (and often better) ways of accomplishing the same thing.

Visual Basic provides these specific Data types not available in REALbasic:

Byte (1 byte)

The best way to work with a byte-sized piece of data is with a MemoryBlock, which is a flexible class offered by REALbasic that will let you work with and manipulate data in just about any way you see fit. Because it is a class, see the MemoryBlock section in Chapter 3, "Classes and Objects."

Char (2 bytes)

Char represents a single character. You can either use a REALbasic string that happens to be one character long, or you can use a 2-byte MemoryBlock in its place.

Long Integer (8 bytes) and Decimal (12 bytes)

Both Long and Decimal represent larger numbers than is currently directly supported by REALbasic. You can easily create 8-byte MemoryBlocks and 12-byte MemoryBlocks for holding data of that size, but if you're planning on doing any math, you'll have to code that yourself.

Date (8 bytes)

Date is a Data type in Visual Basic, but it's a class in REALbasic. See the Date class in Chapter 3.

User-Defined (Structure)

Finally, there is a User-defined type, which is used like a structure in C. You can model this almost directly with the MemoryBlock class, but a better choice in most cases is to create a class instead. A structure is a collection of bytes; you, the programmer, define the meaning of the data in those bytes. So, for example, if you have an 8-byte User-defined structure that describes a person, you could say that the first byte represents the person's age, the next two bytes represent the weight, and so on.

As you will see, classes have properties that are often values just like those I described. You can create a class that has a property that represents a person's age, weight, and so on. The advantage of using a class is that it is generally easier to access the value of the property. Although I'm getting a little ahead of myself, suffice it to say that you can access the property with this kind of syntax:

ClassName.PropertyName 


There may be times when a MemoryBlock is a more efficient approach, but you can expect it to be a little more difficult to work with.

Methods

REALbasic uses the term Method to describe any function or subroutine, whether it is in a module or a class. In other programming languages, method is used exclusively to describe functions or subroutines associated with a class. Although module methods and class (or object) methods are very similar, they are called in slightly different ways depending on whether the method is defined in a module or a class.

When you "call" a method, you are instructing the program to execute the function or procedure in question. Methods are defined in a module or a class, but they can only be called from objects that are instances of the class.

Unlike other programming languages (Java, for instance) REALbasic doesn't have class methods that can be called without instantiating the class. (See Chapter 3 for more information about class instantiation. This fact may change in future versions of REALbasic.) A module can be used as an alternative because modules are also not instantiated.

Functions

I think of functions as questions. When using a function, I am asking a question and expect to get an answer back. With a subroutine, I'm simply telling the computer what to do and really not interested in hearing back from it. Subroutines are sometimes said to have side effects. This means that they perform some tasks, so the state of the program changes in some way (for instance, they save data to a file). It's called a side effect because it happens as a consequence of the instruction, but the instruction itself isn't the center of attention.

Most of the examples I used with operators can be re-expressed using functions. As an example, consider the following function (don't worry about where this function gets created just yet):

Function Add(Num1 as Integer, Num2 as Integer) As Integer // code End 


Add is the name of the function. Inside the parentheses are the parameters Num1 and Num2. These serve the same role that operands do when working with operators. They are the values the function will use to calculate a new value. The data type of the value to be returned follows the parameters. In this case, the return type will be an integer, just like the parameters are.

Sometimes functions can accept optional parameters. When that is the case, I'll enclose that parameter in brackets ([]) to identify it.

Function Add([OptionalParam as String], Num1 as Integer, Num2 as Integer) as Integer   // code End 


I can use this function just like I used the + operator.

Dim answer as Integer answer = Add(1,2) // answer is 3 


When used in code, a function in REALbasic always uses parentheses to wrap the parameters. As you will see, this is in contrast to the standard practice with subroutines, in which you do not use parentheses (although REALbasic lets you use them if you choose).

Subroutines

You have already seen a subroutine in use in the quick start, where you built a simple web browser.

The signature for this subroutine is

Sub LoadURL(anURL as String) 


Sub designates the fact that this is a subroutine. LoadURL is the name of the subroutine and the parameter, anURL, is defined in the parentheses. Note, there is no return value for subroutines. In practice, we wrote this line of code to execute the subroutine:

HTMLViewer1.LoadURL EditField1.text 


In this particular instance, LoadURL is a method of the class HTMLViewer. The parameter bears a little explaining. Text is a property of the class EditField, and its type is string. The signature says that this subroutine takes a string as its only parameter. (The name anURL doesn't really mean anything; it's a placeholder.) EditField1.text is the particular string that's passed in this example.

Arrays

Up until now, I've talked about variables that represent a single value, but there are times when you have a list of values and it would be helpful to be able to refer to them as a single unit. This is when Arrays come in handy.

There are one-dimensional Arrays and multidimensional Arrays. I'll talk about one-dimensional Arrays first.

Declaring Arrays

Like any other variable, you have to declare Arrays before you use them. When you are declaring one-dimensional Arrays, you do not have to specify how many elements are going to be in the list, but you can. Here are three examples of how you declare an Array.

Dim anArray(-1) Dim anArray() Dim anArray(0) 


In the first two examples, I have declared "null" Arrays, or Arrays with nothing in them. They are both equivalent. You might be wondering why I used -1 to declare a null Array rather than 0; that's because when you refer to positions in an Array, you start counting with the number 0, not the number 1. This means that in the third example, I declared an Array with 1 item, not 0. So the first item in an Array is numbered 0, the second item is numbered 1, and so on.

If I declare an Array for four items, I can assign values to those items as follows:

Dim x as Integer Dim anArray(3) as String Dim aString as String anArray 0 = "First item" anArray 1 = "Second item" anArray 2 = "Third item" anArray 3 = "Fourth item" 


Note that to declare an array of four items, I do not place the number 4 in the parentheses of the Dim statement. Instead, I use 3 because this number represent the value of the upper bound of the Array, not the number of elements in the Array. The number of elements in a one-dimensional Array is equal to the number of the upper bound of the array plus one. (See the section "Ubound.")

Using the preceding example, if I want to assign the value of the second item in the Array to the variable aString, I do this:

aString = anArray 1 


ReDim

After you have declared an array, and even after you have populated the array with elements, you are able to resize the array with ReDim. It works just like Dim does, except that you can do it anywhere in the body of a method. If the array already has items in it, ReDim preserves the value of those that are within the range of the new values.

Ubound

If you want to find out the index of the last item in an Array, you can use the Ubound function. Ubound comes from "upper bound," which was mentioned earlier. Ubound is not an Array function. It's one of a list of global functions provided by REALbasic that are always accessible. Ubound takes an Array as a parameter and returns an integer that represents the upper bound of the Array.

Dim x as Integer Dim anArray(3) as String x = Ubound(anArray) 


The value assigned to x is 3. Again, this does not mean that there are three items in the Arraythere are actually four items. What it means is that the index of the last item is 3.

You can also use Ubound to get a reference to the last element in Array.

Dim aString as String Dim anArray(1) as String anArray(0) = "One" anArray(1) = "Two" aString = anArray(Ubound(anArray)) // aString = "Two" 


Ubound can also be used for multidimensional arrays as well. You have to specify the dimension whose upper bound you want. See "Multi-Dimensional Arrays" for an example.

Insert, Append, and Remove

When you have a one-dimensional null Array, you can't use the assignment method from the earlier example because the actual memory has not been allocated for individual items. In other words, anArray(0) doesn't exist yet. One way to assign values to a null Array is with the Append method. This can be used on any one-dimensional Array as a means of adding one more item. It is one of three Array subroutines along with Insert and Remove. The following replicated the Array from the previous example.

Dim x as Integer Dim anArray(-1) as String anArray.Append "First Item" anArray.Append "Second Item" anArray.Append "Third Item" anArray.Append "Fourth Item" 


You can use the Remove subroutine to delete any element of the Array by passing it the position to remove. Add the following code to remove the second item in the list:

anArray.Remove 1 // "Second Item" is deleted 


If you change your mind and want to add it back, use Insert.

anArray.Insert 1 


Note that these are called as subroutines of the Array, which is different than Ubound, which is a global function that is used with Arrays. This is also a good illustration of the difference between subroutines and functions. Subroutines do not return a value, and the parameters are usually not inside of parentheses. Functions do return values and the parameters are always enclosed in parentheses.

Pop

Pop is related to Ubound and allows you to use an Array like a stack. A stack is a list of values. In stack terminology, you push a value onto the stack and then you pop it off. You use append to push a value onto the stack. You use Pop to remove the last value of the stack and return a reference to it. Stacks allow you to manage Last-in/First-out (LIFO) lists, which are a common programming technique.

Dim anArray(-1) as String Dim aString as String Dim x as Integer anArray.append("Dog") anArray.append("Cat") anArray.append("Pheasant") aString = anArray.Pop // aString = "Pheasant" x = Ubound(anArray) // x = 1 because "Pheasant" has been popped 


IndexOf

IndexOf is an Array function that returns the position of a particular value in the array. IndexOf can work on arrays of different types as long as the type used by the indexValue is the same type as the Array itself.

anArray.IndexOf(indexValue as [?], [StartPosition as Integer]) as Integer 


IndexOf is used to search for a value in an Array. It's usually used with an Array of objects rather than scalar values, and it can also be used in combination with the Sort method to sort a list of objects. You pass a value to be searched for and the function returns the position in the array where that term appears. If the value doesn't exist in the Array, -1 is returned.

Dim anArray(-1) as String Dim Position as Integer anArray = Array("Dog", "Cat", "Pig") Position = anArray.IndexOf("Cat") // Position = 1 Position = anArray.IndexOf("Pigeon") // Position = -1 


You can also start your search anywhere in the Array by passing the StartPosition parameter. This might be useful if you are trying to find the same value, but in more than one position in the array.

Dim anArray(-1) as String Dim Pos1 as Integer Dim Pos2 as Integer anArray = Array("Dog", "Cat", "Pig", "Snake", "Cat", "Lizard") Pos1 = anArray.IndexOf("Cat") // Pos1 = 1 Pos2 = anArray.IndexOf("Pigeon",Pos1+1) // Pos2 = 4 


Note that I added 1 to the value of Pos1 as the starting position for the second IndexOf function, otherwise it would return the same value for Pos2 that it returned for Pos1.

The Array Function

A third way of assigning values to an Array is with the Array function. This works only with one-dimensional Arrays (just like Append). You provide a list of values as parameters to the Array function, and it returns an Array containing those values. When you use the Array function with a non-null Array, the original Array is overwritten. If you declare the Array with four items, use the Array function with a list of three items; the resulting Array will have three items:

Dim anArray(3) as String Dim aString, bString as String anArray = Array("One", "Two", "Three") aString = anArray(0) // aString = "One" bString = anArray(2) // bString = "three" 


Assignment by Reference

You can also assign the value of one Array to another. When I defined data types and variables, I said that the variable represents a value of a particular data type and that when you reference the variable, you are referencing the value. The value of the variable is stored at some address in your computer's memory, so when the computer retrieves the value, it first has to find the address and then return the value stored at that address. All this works quietly behind the scenes with intrinsic data types. When you assign the value of one variable to another (when the variable represents a data type), the second variable is separate and distinct from the first. For example, consider the following assignments.

Dim a,b as Integer a = 5 b = a a = 7 


In the first assignment, I set the value of the variable a to 5. Then I set the value of variable b to 5 as well. I then modify a so that its value is now 7. After having done this, the value of b is still 5. Now consider the following example:

Dim anArray(-1) as String Dim bArray(-1) as String Dim aString as String anArray = Array("One", "Two", "Three", "Four") // bArray 'points' to anArray; it is not a copy bArray = anArray anArray.append "Five" aString = join(bArray)// equals "One Two Three Four Five" 


In this example, I declare two Arrays. I populate the first Array with four elements and then assign bArray the value of AnArray. Afterwards, I append another element to anArray. At this point, I convert the values of bArray into a string. If Arrays worked like a normal data type, we would expect bArray to have four elements, which is how many elements anArray had when bArray was assigned the value of anArray. But it doesn't work that way. When you convert bArray to a string, you find that it includes the "Five" element, too, just like anArray does. How can this be?

The reason is that when you say "bArray = anArray" you're not actually setting the value of bArray like you set the value of a data type. Remember that an Array is a series of elements or a group of variables, rather than just one variable. This means that the variable anArray and bArray don't represent a value per se. Instead, they point to a location in memory where the list of values is stored. When you write "bArray = anArray" you are saying that bArray points to the same location in memory that anArray does.

Contrast that behavior with this:

Dim anArray(-1) as String Dim bArray(-1) as String Dim aString as String anArray = Array("One", "Two", "Three", "Four") bArray = Array("Cat", "Dog", "Pigeon", "Rat") // bArray 'points' to anArray; it is not a copy bArray(0) = anArray(0) anArray.append "Five" aString = join(bArray) // "One Dog Pigeon Rat" 


Now what do you expect will happen? When you display the list of bArray's values in a string, this is the list you will get: "One Dog Pigeon Rat". When referring to a specific element in an Array, it's like referring to a variable that represents the value of a data type. It works just like normal assignment does with data types. There's a word for this. The Arrays I've used in the example are references to a value, and not the value itself. As you will see in upcoming chapters, all objects are references, so they exhibit this same behavior. There are also times when you can get a data type variable to act like an object in this sense, using a parameter keyword ByRef, which is discussed in more detail in the section on object-oriented programming.

Multidimensional Arrays

Thus far, you've seen one-dimensional Arrays, but Arrays can actually have up to 20 dimensions. It is probably most common to see a two-dimensional Array that presents the equivalent of a grid of values. The first dimension represents the number of rows in the grid and the second dimension represents the number of columns.

Dim anArray(2,1) as String anArray(0,0) = "First row, first column" anArray(0,1) = "First row, second column" anArray(1,0) = "Second row, first column" anArray(1,1) = "Second row, second column" anArray(2,0) = "Third row, first column" anArray(2,1) = "Third row, second column" 


You can also use Ubound with multidimensional Arrays, as long as you specify the dimension whose upper bound you want to know. The first dimension is referenced by the integer 1, and so on.

Dim x,y as Integer x = Ubound(anArray, 1) // x = 2 y = Ubound(anArray, 2) // y = 1 


As I said, you can have up to 20 dimensions in your Array. Of course, thinking about the array in terms of rows and columns goes out the door.

Dim anArray(2,1,1) as String anArray(0,0,0) = "Some value" anArray(0,0,1) = "A different value" anArray(0,1,0) = "A different dimension" // etc. 


Sort and Shuffle

The Sort function sorts the values in an Array in ascending order. It works only with one dimensional arrays that are strings, integers, singles, and doubles.

anArray.Sort 


Shuffle does the opposite and mixes up the elements in the Array:

anArray.Shuffle 


Split and Join

Split and Join are from a set of functions that operate on strings that are always available in REALbasic.

Split works on a string and converts it into an Array, based on a delimiter that is passed to it. By default, the delimiter is a space. Also, like many functions of this sort that operate on strings, there are two ways of using the Split function:

Split(aString as String, [aDelimiter as String]) As String() aString.Split([aDelimiter as String]) As String() 


With Join, you can combine an Array of strings into a single string while inserting a delimiter between each element in the Array. Like Split, if the delimiter is not specific, a space is used.

Join(anArray() as String, [aDelimiter as String]) Dim anArray(-1) as String Dim aLongString as String Dim count as integer Dim combined as String aLongString = "this*is*a*sentence" anArray = Split(aLongString, "*") count = Ubound(anArray) + 1 


You can also split a string with an empty delimiter (""), which will create an Array of characters.

anArray=Split("I am happy.", "")    anArray(0) is "I", anArray(1) is "", and anArray(2) is "a", and so on. combined = join(anArray, " ") 


Using Arrays with Methods

Arrays can also be used as parameters in methods and as the return value of functions. There are two ways to pass Arrays as parameters:

Sub TestSub(anArray() as String) 


Or

Sub TestSub(ParamArray as String) 


Using either of these techniques when creating a method will enable you to pass an Array as a parameter. Note that when you pass the Array as a parameter, you do not need to use parentheses of any sort. Just pass the name of the Array.

Dim anArray(-1) as String anArray.Append("One") TestSub(anArray) 


To get a function to return an array, the return value has to designate the data type of the return value, as is normally the case, followed by an empty set of parentheses:

Function TestFunc(aString as String) as String() 


Then, when you call this function, the value returned is an Array:

Dim anArray(-1) as String anArray = TestFunc("Some text") 





REALbasic Cross-Platform Application Development
REALbasic Cross-Platform Application Development
ISBN: 0672328135
EAN: 2147483647
Year: 2004
Pages: 149

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net