Multiple MAIN signatures - signature

I have a package with multiple main and I want to define several options:
My code is something like this:
package Perl6::Documentable::CLI {
proto MAIN(|) is export {*}
my %*SUB-MAIN-OPTS = :named-everywhere;
multi MAIN(
"setup"
) { ... }
multi MAIN (
"start" ,
Str :$topdir = "doc",
Bool :v(:verbose($v)) = False
) { ... }
But when I try to actually execute it with:
perl6 -Ilib bin/documentable start -v --topdir=ss
It outputs this line:
Usage:
bin/documentable [--topdir=<Str>] [-v|--verbose] start
I am using %*SUB-MAIN-OPTS but it looks like it does not work neither.

The simplest solution would be to export the dynamic variable %*SUB-MAIN-OPTS, but that is still Not Yet Implemented completely: the export works sorta, but winds up being an empty hash. So not very useful.
Rakudo will call a subroutine called RUN-MAIN when it decides there is a MAIN sub to be run. You can actually export a RUN-MAIN from your module, and set up the dynamic variable, and then call the original RUN-MAIN:
sub RUN-MAIN(|c) is export {
my %*SUB-MAIN-OPTS = :named-anywhere;
CORE::<&RUN-MAIN>(|c)
}
For more information about RUN-MAIN, see: https://docs.raku.org/language/create-cli#index-entry-RUN-MAIN

Related

What is the difference between require with curly braces and require normal?

What is the difference between this
const authController = require("../controller/authController");
and this
const { authController } = require("../controller/authController");
my code doesnt work when i call a function like authController.createUser in second one and i wondered thats why?
Thanks for helps.
The difference between example one and example two is that you are using the Destructuring Assignment method in example two. That means, you can destruct an Object, or Array to have the keys of the object as variables.
So, for example if we take this simple object and we start destructuring:
const someObject = {
something1: "1",
something2: "2",
something3: "3",
something4: "4",
};
const { something1 } = someObject;
console.log(something1) // Returns 1
You see that we can use something1 as a "new variable" instead of accessing it by using someObject.something1.
In your case you are including a module / class with the name authController, but if your module doesn't have a method or key called authController, using the following method:
const { AuthController } = ...
won't work, because it's unable to access this method or key.
So, the first one: authController.createUser() will work because you are loading up the entire module without destructuring the module. If you do something like this const { createUser } = require("authController"), you can use it like createUser(...)
Difference between
const authController = require("../controller/authController");
and
const { authController } = require("../controller/authController");
is, when your module exported by default from your .js file we use first syntax, while if there are several modules getting exported from a single .js file we use the second syntax. Also you cannot have more than one default export from a file. Hope that helps.

nodejs import file and use functions natively

How can I import/require a file, and then use the functions in the file natively?
Say I have file 1:
const file2 = require("./file2.js")
const text = "hello"
file2.print()
And in file 2 I have:
module.exports = {
print:()=>{
console.log(text)
}
}
I want to be able to use functions from another file as if they were in the original file, retaining the variables and objects created in the first file, is this possible?
No, the modules are separate, unless you resort to assigning your variables into the global object and hoping that you can keep track of them without going insane. Don't do that.
Either
pass the data you need around (the best option most of the time), or
maybe add a third module containing the shared state you need and require() it from both file 1 and file 2
No!
But
The regular pattern of shared context is that you create a context and share it. The most simple form of it is something like this:
//In file 1 -->
let myContext = {
text: 'hello'
}
file2.print(myContext);
//In file 2 -->
module.exports = {
print:(ctx)=>{
console.log(ctx.text)
}
}
However
JS has some inbuilt support for context. Something like this:
//In file 1 -->
let myContext = {
text: 'hello'
}
let print = file2.print.bind(myContext);
print();
//In file 2 -->
module.exports = {
print: function(){
console.log(this.text)
}
}
Notice the removal of the argument and changing the arrow function to a function expression.

Capturing a module output

Say we have this module:
unit module outputs;
say "Loaded";
And we load it like this
use v6;
use lib ".";
require "outputs.pm6";
That will print "Loaded" when it's required. Say we want to capture the standard output of that loaded module. We can do that if it's an external process, but there does not seem to be a way for redirecting *OUT to a string or,if that's not possible, to a file. Is that so?
You could try use IO::String:
use v6;
use lib ".";
use IO::String;
my $buffer = IO::String.new;
with $buffer -> $*OUT {
require "outputs.pm6";
};
say "Finished";
print ~$buffer;
Output:
Finished
Loaded
See also If I reassigned OUT in Perl 6, how can I change it back to stdout?
Temporarily reassigning $*OUT so that .print calls append to a string:
my $capture-stdout;
{
my $*OUT = $*OUT but
role { method print (*#args) { $capture-stdout ~= #args } }
require "outputs.pm6" # `say` goes via above `print` method
}
say $capture-stdout; # Loaded

How does Node.js module system handle modifying and accessing variable of the same module of different versions?

I have a custom Node.js module fooModule that has a private variable foo and public getter and setter to modify this variable.
I have another two modules: zooModule depends on the fooModule#^1.0.1 and cannot use pre-release so far and barModule that depends on the fooModule#^1.0.2-0 (pre-release patch version that contains some fix) and zooModule at the same time.
The barModule firstly sets the foo variable value and then zooModule reads the value of foo.
I have noticed that when the version of the fooModule dependency is the same, then it works as expected, in other words the foo variable is shared between two modules. However, using different versions results in undefined when accessing foo from zooModule.
Here is a small pseudo example to demonstrate the logic. Each of the modules is a standalone npm package.
// fooModule.js
let foo;
export const getFoo = () => foo;
export const setFoo = (newFoo) => foo = newFoo;
// zooModule.js uses v.1.0.1 of the fooModule
import { getFoo } from './fooModule.js'
export const zooFunc = () => {
const zoo = getFoo();
if(!zoo) return;
...
return zoo; //result depends on zoo
};
// barModule.js uses v.1.0.2-0 of the fooModule
import { setFoo } from './fooModule.js'
import { zooFunc } from './zooModule.js'
setFoo('foo');
zooFunc(); // What is the output?
As far as I am concerned, in case of different versions of the fooModule, we become two different instances of the module and accordingly of the variable foo?
I tried to explain the question best I could, but it was hard to explain what I mean, sorry if it is still unclear.
Could give me some hints where to read more about this or give some explanation on how this is supposed to work. Thanks for your time.
EDIT:I forgot to mention that I have this use case in a frontend project bundled by a webpack.

check if a class exists

Is there a way to check in manifest files if a given class exists?
I want to do something like this:
class foo {
if exists( Class["foo::${lsbdistcodename}"] ) {
include foo::${lsbdistcodename}
}
}
So I can easily add distrubution / version specific classes which are then automatically included.
You should use defined instead of exists statement.
The following snippet works for me:
class foo {
if defined( "foo::${lsbdistcodename}") {
notify {'defined':}
include "foo::${lsbdistcodename}"
}
}
class foo::precise {
notify{'precise':}
}
[assuming you're running puppet version > 2.6.0]

Resources