How to import external vars and functions from external modules? - xquery

test2.xqy:
import module namespace myNS = "http://test.org/module1" at "./namespace.xqy";
element test
{
}
namespace.xqy:
module namespace myNS = "http://test.org/module1";
declare variable $myNS:srcDoc:="test2.xml";
declare variable $myNS:defaultXMLNS:="http://www.test.com#";
declare variable $myNS:defaultXMLBase:=$defaultXMLNS;
Command line:
$ basex test2.xqy
Stopped at /Users/jack/Documents/xqy/namespace.xqy, 5/53:
[XPST0008] Undefined variable $defaultXMLNS.
I didn't find doc about how to import vars and functions from external modules. So I try it in a intuitive way. The error says there is no definition for $defaultXMLNS. I did define it, but with a namespace prefix.

You forgot to define the namespace on the right-hand side of the assignment:
declare variable $myNS:defaultXMLBase:=$defaultXMLNS;
(: ^ no namespace defined :)
Thus, $defaultXMLNS is searched in the default namespace, where it is not registered. Apply the namespace instead:
declare variable $myNS:defaultXMLBase:=$myNS:defaultXMLNS;
If you do so, you can later access the value like this:
import module namespace myNS = "http://test.org/module1" at "./namespace.xqy";
element test
{
$myNS:srcDoc
}

Related

Scope and statically known namespaces in XQuery

consider a library module ctx
xquery version "3.1";
module namespace ctx="module/ctx";
declare function ctx:resolve (
$ctx as function(xs:string) as xs:QName
) as function(xs:string, xs:integer) as function(*)? {
function ($name as xs:string, $arity as xs:integer) as function(*)? {
function-lookup($ctx($name), $arity)
}
};
and a library module a
xquery version "3.1";
module namespace a="module/a";
declare function a:f () { "a:f" };
And a main module
xquery version "3.1";
import module namespace a="module/a" at "a.xqm";
import module namespace ctx="module/ctx" at "ctx.xqm";
ctx:resolve(xs:QName(?))("a:f", 0)()
Is it safe to assume that the function reference returned by xs:QName(?) will keep the context in which the namespace a is declared so that the main module will output "a:f"?
This does work in eXist-db (tested on 5.3.0) but I am not sure if this code is portable to other XQuery 3.1 processors.
---- UPDATE ----
What does not work in eXist-db 5.3.0 is
import module namespace ctx="module/ctx" at "ctx.xqm";
declare namespace app = "app";
declare function app:f () { "app:f" };
ctx:resolve(xs:QName(?))("app:f", 0)()
It's an excellent question.
If you used a named function reference xs:QName#1, then you would find the answer in §3.1.6:
Furthermore, if the function returned by the evaluation of a
NamedFunctionRef has an implementation-dependent implementation, then
the implementation of this function is associated with the static
context of this NamedFunctionRef expression and with the dynamic
context in which the NamedFunctionRef is evaluated.
That's rather arcane language, but what it means is that the function you get back uses the static and dynamic context of the named function reference itself (and not the context at the point where the function is actually called).
For a partial function application xs:QName(?) the language is even more impenetrable:
Implementation: The implementation of F. If this is not an XQuery 3.1
expression then the new function's implementation is associated with a
static context and a dynamic context in one of two ways: if F's
implementation is already associated with contexts, then those are
used; otherwise, SC and DC are used.
I think the spec is assuming (without justification) that built in functions like xs:QName will have an implementation that is not an XQuery 3.1 expression, so the second sentence applies. I really don't know quite what it intends by the phrase "already associated with contexts" - perhaps it's concerned with the case where F is already a partially applied function. But in any case, I'm reasonably sure that the intent is that "SC and DC are used" - that is, xs:QName(?) works exactly like xs:QName#1, it uses the static and dynamic context at the point where the expression xs:QName(?) is evaluated.
You're quite right to be concerned that you can't assume that what existing products do is what the spec says must happen. But in this case, I think they are getting it right.
Is it safe to assume that the function reference returned by xs:QName(?) will keep the context in which the namespace a is declared so that the main module will output "a:f"?
Tested successfully with BaseX 10.3.
Had to fix ctx as it was deemed syntactically incorrect by BaseX (missing as <Type>) for the result of ctx:resolve(). Just added as function(*)? . Here is the corrected code:
xquery version "3.1";
module namespace ctx="module/ctx";
declare function ctx:resolve (
$ctx as function(xs:string) as xs:QName
) as function(xs:string, xs:integer) as function(*)? {
function ($name as xs:string, $arity as xs:integer) as function(*)? {
function-lookup($ctx($name), $arity)
}
};

Using environment variables in Typescript

Is there a proper way to include environment variables in a .ts file? They are declared in wrangler.toml or through the CLI, but Typescript won't know they are there.
Currently I either use a .js file to declare these vars and then import into a .ts
//env.js
const SOMEVAR = SOMEVAR
Or I will need to use a #ts-ignore comment.
I've tried process.env but as expected this fails as the script isn't run in Node.
You can inform TypeScript of your global variables by using the declare global { ... } syntax in your script:
declare global {
const SOMEVAR: string
const ANOTHERVAR: string
}
// now you can use SOMEVAR and ANOTHERVAR as global vars

Can't extends imported class

class A {}
class B extends A {}
the code above work fine but when I try to do the same with an imported class, I't does not work.
declare module 'a' {
declare export class A {}
}
import typeof { A } from 'a';
class B extends A {}
Cannot reference type A [1] from a value position
can anyone solve this ?
https://flow.org/try/#0CYUwxgNghgTiAEBbA9sArhBByKX4G8AoeeUSWBEADwAdkYAXecgZxfgEECBfQ3wgJaI6jeAwCeNEMgBmBTvG4ACmTGSJ4OLAG5ChVuwBC8agxAA7YOy75uQA
When you define a class you actually define both a type and a Javascript class, and both have the same name. Types only exist at compile time - they have no runtime representation. In your example you imported the type, but not the runtime value.
// imports the type only
import typeof { A } from 'a'
// imports both the type and the runtime value
import { A } from 'a'
The type informs Flow what the class does for purposes of type checking. But the runtime value is what defines the implementation to be executed. The compiled program must have a reference to the runtime value to instantiate or to extend a class. In other words, remove the typeof keyword and it should work.

s4 classes exported by default if presence of an initialize method

I thought classes needed an exportClass directive in NAMESPACE to be exported,
but
Classes defined in a package but not exported are nevertheless exported if there is an initialize method for the class in the code base.
that is to say I can create an instance of the class event though I exported nothing.
so
setClass("example", slots = c( title = "string"))
setClass("example2", slots = c( title = "string"))
and
setMethod("initialize","example, function(.Object, title) {
.Object#title <- title
. Object
})
in the package R directory and NAMESPACE present but with no export directives in it,
results in the possibility to create an instance of the class
library(example_package)
new("example") # ok
new("example2") # fails
I guess this is because initialize is a generics that is already defined
but does it mean you cannot prevent class instantiation by the user of the package if there is an initialize method for the class ?
or maybe put the initialize inside the setClass instruction ?

Difference between "using MyNameSpace;" and "namespace MyNameSpace"

Hello I am new to asp.net. I am confused what is the difference between "using MyNameSpace;" and "namespace MyNameSpace". My demo code is as follow...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MyNameSpace;
namespace MyNameSpace
{
public partial class DemoPage : System.Web.UI.Page
{
My code here
}
}
In the above code is there any difference between the two highlighted statements or not. If yes then what is it?
Thanks in advance...
Yes, they provide complementary services.
A using directive like this:
using MyNamespace;
Tells the compiler to look in the namespace MyNamespace when resolving simple names - so if you have a type called MyNamespace.Foo, you can just use Foo in your source to refer to it when you've got this using directive.
However, the namespace declaration effectively says, "Anything I declare within this block is in the given namespace". So to declare the MyNamespace.Foo type, you'd use:
namespace MyNamespace
{
public class Foo
{
...
}
}
Do you see? The using directive says that you want to use things in a particular namespace, whereas the namespace declaration is about putting things into a particular namespace.
using is used for creating a "shortcut" to typenames within that namespace. This is only needed when the code you write is within another namespace. namespace is used for defining a namespace:
Example
In file first.cs:
// define the namespace "SomeNamespace"
namespace SomeNamespace
{
// define a type within the namespace
class SomeClass { }
}
In file second.cs:
using SomeNamespace;
// define the namespace "OtherNamespace"
namespace OtherNamespace
{
class OtherClass
{
void SomeMethod()
{
// use the type "SomeClass", defined in the "SomeNamespace" namespace
// note that without the using directive above we would need to write
// SomeNamespace.SomeClass for this to work.
SomeClass temp = new SomeClass();
}
}
}
In the above code sample, the declaration of the temp variable does not need to include the namespace, since it is mentioned in a using directive.
Yes, there is a difference. The namespace statement is used to create a namespace, while the using statement is used to make the compiler regognise an already existing namespace.
In your code the using statement has no effect, as all your code is in that namespace so it already knows about it.
As you have using System.Web.UI, the System.Web.UI.Page identifier could be written as just Page as the compiler knows about the classes in that namespace. If you wouldn't have that using statement, you would need the fully qualified name for the compiler to know where to find the class.

Resources