Pointers and references: Difference between revisions
Add Ecstasy example
(Add Ecstasy example) |
|||
(5 intermediate revisions by 3 users not shown) | |||
Line 494:
===Pointers===
Pointers are declared like so, optionally with the type or program they will point to:
<syntaxhighlight lang="
<code>USAGE POINTER</code> data items are used in conjunction with <code>BASED</code> data items, with <code>ALLOCATE</code> optionally giving a pointer the address of the allocated memory. Pointers can also be used to free allocated memory, which will cause the pointer to be set to <code>NULL</code>.
<syntaxhighlight lang="
PROCEDURE DIVISION.
FREE ptr</syntaxhighlight>▼
ALLOCATE heap-item RETURNING ptr
*> ...
▲ FREE ptr</syntaxhighlight>
<code>USAGE PROGRAM-POINTER</code> data items are used to point to programs and their entry points.
{{works with|OpenCOBOL}}
{{works with|Visual COBOL}}
<syntaxhighlight lang="
Both types of pointer support basic pointer arithmetic.
<syntaxhighlight lang="
SET ptr2 DOWN BY LENGTH OF foo</syntaxhighlight>
Pointers can also be set to point to where other pointers are pointing or to other pointers themselves.
<syntaxhighlight lang="
SET ptr2 TO ADDRESS OF ptr3 *> ptr2 points to ptr3</syntaxhighlight>
To alter the value pointed to by a pointer, the <code>SET</code> statement is needed once again and is used to set the address of <code>BASED</code> or <code>LINKAGE SECTION</code> data items, which can then be used to modify the data.
<syntaxhighlight lang="
MOVE "bar" TO foo</syntaxhighlight>
===References===
Object references are declared like so, optionally with the class/interface they will reference:
<syntaxhighlight lang="
They contain either a reference to an object or <code>NULL</code>.
They are initialised using by invoking a class constructor, and set using the <code>SET</code> statement.
<syntaxhighlight lang="
SET another-obj-ref TO obj-ref</syntaxhighlight>
Line 672 ⟶ 675:
→ 666
</syntaxhighlight>
=={{header|Ecstasy}}==
In Ecstasy, all values are references to objects. These references are like pointers in C, but address information is not accessible, and no arithmetic operations can be performed on them. Additionally, each reference is itself an object, providing reflective information about the reference.
Objects are always accessed and manipulated through references, using the <code>.</code> ("dot") operator.
Ecstasy uses call-by-value. When passing arguments, all arguments are references, passed by value.
<syntaxhighlight lang="ecstasy">
module test {
@Inject Console console;
public class Point(Int x, Int y) {
@Override String toString() = $"({x},{y})";
}
void run() {
Point p = new Point(0, 0);
console.print($"{p=}");
// obtain the reference object itself
Ref<Point> r = &p;
console.print($"{r.actualType=}");
}
}
</syntaxhighlight>
{{out}}
<pre>
x$ xec test
p=(7,7)
r.actualType=Point
</pre>
=={{header|Forth}}==
Line 1,008 ⟶ 1,046:
all(.[]; type == "string" or (type == "number" and floor == .));
# The JSON Pointer spec allows 0 both for indexing an array and for retrieving a key named "0".
# like getpath() but for jsonpointer pointers▼
# disambiguate($k) accordingly disambiguates $k w.r.t. `.`.
# $k should be a string or integer.
# If $k is a string and . is an object then: if has($k) then $k else null end.
# If $k is an integer and . is an array, then emit $k.
# If $k is an integer-valued string and . is an array then exit $k|tonumber.
# Otherwise emit null
def disambiguate( $k ):
if ($k|type) == "string"
then if type == "object" then $k
elif type == "array" and ($k|test("^[0-9]+$"))
then ($k|tonumber)
else null
elif ($k|type) == "number" and type == "array"
then $k
else null
end;
# $array should be an array of strings and integers.
# Emit the disambiguated array, suitable for running getpath/1.
# Emit null if disambiguation fails at any point.
def disambiguatePath($array):
. as $in
| reduce $array[] as $x ([];
if . then . as $path
| ($in | getpath($path) | disambiguate($x)) as $y
else null
end
else .
end);
▲# getjsonpointer() is like getpath() but for jsonpointer pointers
def getjsonpointer($pointer):
if $pointer == "" then . # special case
else
# first decode ~1, then ~0
($pointer | split("/") | .[1:]
| map(gsub("~1"; "/") | gsub("~0"; "~")
| disambiguatePath($array) as $apath
| if $apath then getpath($apath) else null end
end;
# like getpath() but allow $p to be a jsonpointer or an array
Line 1,027 ⟶ 1,102:
def deref($pointer):
def resolve($x):
if ($x | type) == "object"
▲ . as $in
|
▲ | if $ref then getpointer($ref)
▲ else $x
▲ end
else $x
end
else $x
end;
if ($pointer|type) == "string"
Line 2,129 ⟶ 2,203:
The following example illustrates the difference by passing both value and reference type parameters to a function. Note that in Wren parameters are always passed by value.
<syntaxhighlight lang="
// The value and the reference are copied to their respective parameters.
var f = Fn.new { |s, l|
|