This section describes the differences between Lasso Professional 8 and Lasso 9, and how developers can adapt their code to address those differences.
Server Admin
The Server Admin tool has moved - it's now accessible via the following URLs:
http://localhost/lasso9/admin
http://www.example.com/lasso9/admin
Setting Up Datasources
The Security interface in Lasso SiteAdmin from Lasso Professional 8 has been removed. Datasource permissions are now handled at the database server itself.
See the documentation for your datasource for how to set up users and accounts with the proper permissions. It is strongly advised to create users that have the least privileges necessary.
When setting up a datasource in Lasso 9 Admin, while entering the name of the server, enter the hostname or IP address of the server. Previously the name field was an arbitrary label of the connection information.
Lasso 9 Admin - Edit Datasources
Here is a short video showing the setup of a MySQL datasource in Lasso 9. Although this is for MySQL, It is useful in helping setting up datasources in many other types of databases as well.
Assignment and References
Assignments in Lasso 8 always create a copy of the object on the right-hand side of the assignment unless you use the @ operator. The @ operator gets a reference to an object which you could then assign to a variable. From that point on, the two variables will always point to the same object. Assignments in Lasso 9 always create a reference to the object on the right-hand side of the assignment. However, there is no way to link variables so that if you reassign one of them the other is also reassigned to the same object.
Lasso 8: $foo and $bar point to two different string objects that have the value of "moose" while $foo and $baz both point to the same string object that has the value of "moose"
Lasso 9: $foo, $bar, and $baz all point to the same string object. Lasso 9 ignores the @ operator as all assignments create a reference to an object instead of duplicating the object and creating a reference to the copy.
In Lasso 8, once you created a variable as a reference to another using the @ operator, the two variables would always refer to the same object, so if one received a different assignment, the other would be reassigned too. Lasso 9 does not have this ability to link variables together so that reassigning one also reassigns the other. In Lasso 9, assignment always creates a new reference to an object without affecting the assignments already made to other variables.
Lasso 8: Both $foo and $baz have been reassigned to point to a string object with the value of "hair" while $bar has been reassigned to a string object that contains the value of "wild".
Lasso 9: $foo still points to the string object that has the value of "moose" while $bar has been reassigned to another string object that has a value of "wild" and $baz has been reassigned to another string object that has the value of "hair".
From these examples, it may appear not to matter that when you assign $foo to $bar in Lasso 9 that they both refer to the same object because as soon as you do a reassignment to either of them, they no longer refer to the same object. For the most part there is no need to worry, but problems can arise when you use member tags that change the value of the object in place. In the example code below, we want one variable to hold the original value and the other to hold a lowercase copy of that value:
In Lasso 8, var('foo_lowercase') = $foo; creates a copy of the object that $foo refers to and gives that copy to $foo_lowercase since it only creates a reference if you use the @ operator. In Lasso 9, var('foo_lowercase') = $foo; has $foo_lowercase refer to the same object as $foo. What does all this mean? Well, let's say that action_param('search_term') returned "Moose Hair". In Lasso 8, the value of $foo would be "Moose Hair" while the value of $foo_lowercase would be "moose hair". In Lasso 9, since they refer to the same object, both would return a value of "moose hair".
To take another example, this time with elements of an array:
Code
Lasso 8
Lasso 9
var('foo') = array('moose', 'hair', 'moose');
var('bar') = $foo->get(1);
$bar now contains a copy of the value in position 1 of the array $foo
$bar now contains a reference to the value in position 1 of the array $foo
$bar->replace($bar, 'wild');
the value in $bar is now a new string 'wild', $foo is unaffected
$bar still contains a reference to the value in position 1 of the array $foo, but that value has been updated to the string of 'wild'
$bar = 'moosehair';
$bar now contains a string 'moosehair'
$bar now contains a string value 'moosehair' and no longer has a reference the array $foo
$bar;
outputs the current value of $bar, 'moosehair'
outputs the current value of $bar, 'moosehair'
$foo;
outputs the current contents of the array $foo which has been unchanged throughout the process
outputs the current contents of the array $foo including the newly updated value of position 1
In Lasso 8, $bar would be set to a copy of the object in $foo->get(1), but in Lasso 9, it is set as a reference to that object. What that means is that in Lasso 8 when you call the member function string->replace, it has no effect on the item in the array, but in Lasso 9 since both variables refer to the same object, the array will see the change in value to "wild". When we reassign $bar to "moosehair", the item in the array is unaffected in both Lasso 8 and 9 as we are assigning $bar to refer to a new object. Below are the results running in the various versions:
Lasso 8
moosehair
array: (moose), (hair), (moose)
Lasso 9
moosehair
array(wild, hair, moose)
If you find yourself in this situation and wanting the Lasso 8 default of copying the object, there are a couple of things you can do. You can use a cast method to cast the object as a type. Cast methods always return a new object, so even if you cast the object as the same type, you will get a new object. Another option is to use Lasso 9's built-in ->asCopy method.
Examples:
// Using the cast method "string()" to get a new string object
var('bar') = string($foo->get(1));
//Using the built-in ->asCopy method to get a new string object
var('bar') = $foo->get(1)->asCopy;
Either way, you now have $bar and $foo referring to different objects, so using member methods on one will not affect the other.
In summary, Lasso 9 assignments behave as if you had used the @ operator in Lasso 8 to not create a new object for the assignment. However, unlike Lasso 8, a future reassignment does not cause all variables linked by reference to one object to refer to the newly assigned object - only the variable being reassigned has the new reference to the new object. Since assignment in Lasso 9 creates a reference to the object, using member tags that change the value of the object in place will cause all variables who refer to that object to see that change. If you need to avoid this, you can cast the object as a type (even the same type), or use the built-in ->asCopy method to return a copy.
How values are stored globally
In versions prior to Lasso 9, values stored globally were set using "global('varname' = value);" syntax.
Lasso 9 does not support the "global variable", instead uses the concept of "threading".
Threading in Lasso 9 is designed to be easy to use and safe in an environment where many requests are made to read these values simultaneously.
Simple usage:
define varname => value
varname // outputs the value of the thread "varname" set above
As of Lasso 9.1, multiple sites are now configured using the Lasso Instance Manager admin interface. This is accessed through the url: /lasso9/instancemanager
Serialization
Due to architectural changes, ->unserialize no longer exists in Lasso 9.
Note: this limitation only applies to LOCAL( ) variables, you still can do this with VAR( ) variables.
Syntax Differences and Incompatabilities
Use parens syntax rather than colons
Although Lasso 9 can understand the old colon syntax, in some cases it could get confused and output an error. It's recommended that priority is given to de-colonize existing code, for Lasso 9.
Example:
field('this')
// instead of
field:'this'
Always use + concatenation and not implicit concatenation
Example:
// use this
#price = '$'+field('price')
// instead of this
#price = '$'field('price')
For compatibility, Lasso 9 will handle implicit concatenation in some instances, but only for parenthesised expressions or expressions which are part of a parameter.
Do not use strings when a tag parameter expects an integer
Note: this limitation only applies to LOCAL( ) variables, you still can do this with VAR( ) variables.
Handlers take effect only when they are reached
Versions of the language prior to Lasso 9 behaved as though all handlers were located at the top of the current scope/block. In Lasso 9, handlers go into effect only as they are encountered in the running code. This means Lasso 9 provides finer grained control over handling errors and other conditions.
In Lasso 9, the handle which closes the file will only ever execute if the file object is successfully created. In Lasso Professional 8.6 and earlier, the handle would have been implicitly moved to the top of the code above the 'local' definition which creates the file. This causes the problem of not knowing there is a valid file object to be closed.
Referencing a var with @ will not work
The required change means that any occurrence of this within the code has to be upgraded. See the Language Reference section.
The (:) shortcut makes a 'staticarray'
In Lasso 8.5, the syntax (:), or (: item, item, etc.) would create an array object containing the given items. In Lasso 9, the (: ...) syntax creates a staticarray object, which is an effecient, but non-resizable container object.
Testing a field or var against the empty string
If you are using the code below in 8.5 to check for either a field with an empty string or a field with a null value, it will only check for an empty string in 9:
if(field('someField') !='');
To get this to work in both 8.5 and 9, it's advised to explicitly cast the field to a string prior to comparing it. This will leave an empty string as is and convert the null into an empty string. Preferred syntax:
if(string(field('someField')) != '');
nslookup difference
When a reverse lookup doesn't find anything, LP8 returns the IP address while L9 returns null.
Using array->join to make sum will not work
array(1,2,3)->join;
This kind of shortcut used to perform an addition integers in an array, in L9 it no longer does. This will output 123 as expected from a concatenation method.
In LP8 it was possible to search the built-in "params" map when inside a define_tag block by passing the name of the param with its hyphen. In L9, it's required to remove the hyphen: params->find('-a') for this code to work.
ForEach({...}) syntax will conflict with L9 brackets syntax
{ ... } is the main building block in L9, and this particular syntax in L8 will throw an error.
None of the Lasso 8 link_* tags, such as link_prevGroup or link_nextGroup, are supported.
Arbitrary code in define_type not supported
Although the behavior was deprecated, LP8 allowed arbitrary code to be nested within a type definition and that code would be run when the type was created. Lasso 9 supports LP8's define_type;/define_type for compatibility purposes, but does not support any arbitrary body code. Move any old body code into the type's onCreate method(s).
Arbitrary Parameters Only Supported with Rest Syntax
In Lasso 8, you could pass as many parameters as you wanted to a method even if the method definition did not define those parameters. These additional parameters could then be accessed by using the [params] method. (That method also contained the information for all the defined parameters too.) In Lasso 9, if you want a method to be able to take arbitrary parameters, you must use the Rest syntax in the method signature.
Field values unavailable after an "-add" inline action
Lasso 9 does not support using the [field] or [column] methods inside an [inline(-add, ...)] action to view the values in the newly added row.
->onConvert is not supported
Lasso 9 does not support "onConvert". Use ->asString instead to customize how your object is represented as a string value.