Next

Prev

Prev-tail

Tail

Up

Chapter 16
Migration from urbiscript 1 to urbiscript 2

This chapter is intended to people who want to migrate programs in urbiscript 1 to urbiscript 2. Backward compatibility is mostly ensured, but some urbiscript 1 constructs were removed because they prevented the introduction of cleaner constructs in urbiscript 2. When possible, urbiscript 2 supports the remaining urbiscript 1 constructs. The Kernel1 (Section 20.28) object contains functions that support some urbiscript 1 features.

 16.1 $(Foo)
 16.2 delete Foo
 16.3 emit Foo
 16.4 eval(Foo)
 16.5 foreach
 16.6 group
 16.7 loopn
 16.8 new Foo
 16.9 self
 16.10 stop Foo
 16.11 # line
 16.12 tag+end

16.1 $(Foo)

This construct was designed to build identifiers at run-time. This used to be a common idiom to work around some limitations of urbiscript 1 which are typically no longer needed in urbiscript 2. For instance, genuine local variables are simpler and safer to use than identifiers forged by hand to be unique. In order to associate information to a string, use a Dictionary (Section 20.11).

If you really need to forge identifiers at run-time, use setSlot, updateSlot, and getSlot, which all work with strings, and possibly asString, which converts arbitrary expressions into strings. The following table lists common patterns.



Deprecated Updated


var $(Foo) = ...;

setSlot(Foo.asString, ...);

$(Foo) = ...;

updateSlot(Foo.asString, ...);

$(Foo)

getSlot(Foo.asString);



16.2 delete Foo

In order to maintain an analogy with the C ++ language, urbiscript used to support delete Foo, but this was removed for a number of reasons:

For these reasons, and others, delete Foo was removed. To remove the name Foo, run removeSlot("Foo") (Section 6.1) — the garbage collector will reclaim memory if there are no other use of Foo. To remove the contents of Foo, you remove all its slots one by one:

 
class Foo 
{ 
  var a = 12; 
  var b = 23; 
} | {}; 
function Object.removeAllSlots() 
{ 
  for (var s: localSlotNames) 
    removeSlot(s); 
} | {}; 
Foo.removeAllSlots; 
Foo.localSlotNames; 
[00000000] []  

16.3 emit Foo

The keyword emit is deprecated in favor of !.



Deprecated Updated


emit e;

e!;

emit e(a);

e!(a);

emit e ~ 1s;

e! ~ 1s;

emit e(a) ~ 1s;

e!(a) ~ 1s;



The ? construct is changed for symmetry.



Deprecated Updated


at (?e)

at (e?)

at (?e(var a))

at (e?(var a))

at (?e(var a) if a == 2)

at (e?(var a) if a == 2)



16.4 eval(Foo)

eval is still supported, but its use is discouraged: one can often easily do without. For instance, eval was often used to manipulate forged identifiers; see Section 16.1 for means of getting rid of them.

16.5 foreach

The same feature with a slightly different syntax is now provided by for. See Section 19.6.5.2.

16.6 group

Where support for groups was a built-in feature in urbiscript 1, it is now provided by the standard library, see Group (Section 20.24). Instead of

 
group myGroup {a, b, c}  
write
 
var myGroup = Group.new(a,b,c)  

16.7 loopn

The same feature and syntax is now provided by for. See Section 19.6.5.3.

16.8 new Foo

See Section 9.5 for details on new. The construct new Foo is no longer supported because it is (too) ambiguous: what does new a(1,2).b(3,4) mean? Is a(1,2).b the object to clone and (3,4) are the arguments of the constructor? Or is it the result of a(1,2).b(3,4) that must be cloned?

In temporary versions, urbiscript 2 used to support this new construct, but too many users got it wrong, and we decided to keep only the simpler, safer, and more consistent method-call-style construct: Foo.new. Every single possible interpretation of new a(1,2).b(3,4) is reported below, unambiguously.

16.9 self

For consistency with the C ++ syntax, urbiscript now uses this.

16.10 stop Foo

Use Foo.stop instead, see Tag (Section 20.61).

16.11 # line

Use //#line instead, see Section 19.1.3.

16.12 tag+end

To detect the end of a statement, instead of

 
mytag+end: { echo ("foo") },  

use the leave? method of the Tag (Section 20.61) object:

 
{ 
  var mytag = Tag.new("mytag"); 
  at (mytag.leave?) 
    Channel.new("mytag") << "code has finished"; 
  mytag: { echo ("foo") }, 
}; 
[00000002] *** foo 
[00000003:mytag] "code has finished"