Pointers and references: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 939: Line 939:


Java is call-by-value. When passing arguments, you are either passing primitives by value or references by value. There is no such thing as "passing an object" as objects are not values in the language. As noted above, if the object that the reference is pointing to is mutable, then it is possible to modify that object's state through the reference. Then if the calling function has a reference to the same object, they will see that modification through the reference. So if you want to reflect changes in an argument back to the caller, one thing that you can do is wrap the argument as a field in an object, then modify the object through the reference.
Java is call-by-value. When passing arguments, you are either passing primitives by value or references by value. There is no such thing as "passing an object" as objects are not values in the language. As noted above, if the object that the reference is pointing to is mutable, then it is possible to modify that object's state through the reference. Then if the calling function has a reference to the same object, they will see that modification through the reference. So if you want to reflect changes in an argument back to the caller, one thing that you can do is wrap the argument as a field in an object, then modify the object through the reference.

=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''

'''Also works with fq, a Go implementation of a large subset of jq'''

In the context of JSON, "JSON Pointer" usually refers to RFC 6901,
which defines a string format for accessing values from a JSON document
in an analogous manner as XPath defines a mechanism for accessing values from an XML document.

jq has no built-in support for JSON Pointer as it already provides an analogous mechanism
based on paths expressed as arrays. Specifically, a JSON array of strings and integers can be used to specify
a path, $p, and jq provides a function `getpath($p)` for accessing the value at the given path, $p.

In this entry, we will use the term "JSON pointer" to refer to either a JSON Pointer string, or a jq array path.

Neither JSON nor jq provides a mechanism for handling embedded JSON pointers, but a common convention
is to use a JSON object with a key named "$ref" as a reference. We will adopt this convention here,
as illustrated by the following JSON document:

<pre>
[
{
"name": "John",
"birthplace": "London"
},
{
"name": "Jim",
"birthplace": "Paris",
"father": {
"$ref": "/0"
}
}
]
</pre>

In the following, we extend jq's support for array paths to JSON pointers, and
add functionality for dereferencing "$ref" values, whether expressed as
array paths or JSON Pointer values.

Thus we will be able to write expressions such as:
<pre>
deref([1, "father"])
deref( "/1/father" )
</pre>
to retrieve the details concerning Jim's father.

We shall also ensure that deref can be used with jq's native query capabilities:
<pre>
deref( .[1]["father"] )
deref( .[1] | .father )
</pre>

'''Library'''
<syntaxhighlight lang=jq>
# Convert a jq array path to a JSON Pointer
def jsonpointer:
def encode: gsub("~"; "~0") | gsub("/"; "~1");
reduce .[] as $x
("";
if ($x|type) == "string" then "\(.)/\($x|encode)"
else . + "/\($x)" end );

# Is the input syntactically a jq array path?
def isarraypath:
type == "array" and
all(.[]; type == "string" or (type == "number" and floor == .));

# like getpath() but for jsonpointer pointers
def getjsonpointer($pointer):
# first decode ~1, then ~0
($pointer | split("/") | .[1:]
| map(gsub("~1"; "/") | gsub("~0"; "~") | if test("^[0-9]+$") then tonumber else . end)) as $jqpath
| getpath($jqpath);

# like getpath() but allow $p to be a jsonpointer or an array
def getpointer($p):
if ($p|type) == "string" then getjsonpointer($p)
elif ($p|isarraypath) then getpath($p)
else $p
end;
# dereference $pointer, but not recursively.
# $pointer can be a jsonpointer pointer, or a jq array path,
# but one can also call deref(query) where `query` is a jq query yielding a $ref object.
def deref($pointer):
def resolve($x):
. as $in
| if ($x | type) == "object"
then $x["$ref"] as $ref
| if $ref then getpointer($ref)
else $x
end
else $x
end;

if ($pointer|type) == "string"
then resolve(getpointer($pointer))
elif ($pointer|isarraypath)
then resolve(getpath($pointer))
else resolve($pointer)
end;
</syntaxhighlight>
'''Examples'''
These examples correspond to the John/Jim JSON document shown above.
In each case, the result would be "John".
<pre>
getpointer("/0/name") # JSON Pointer

getpointer([0, "name"] ) # array path

deref("/1/father").name # JSON Pointer

deref([1,"father"] ).name # array path

deref(.[1]["father"] ).name # jq query

deref(.[1] | .father).name # jq query

deref(.[] | select(.name == "Jim").father ).name # jq query
</pre>


=={{header|Julia}}==
=={{header|Julia}}==