Passing quoted arguments to a REBOL 3 script - rebol

I've found it almost impossible to pass quoted arguments (containing spaces) to REBOL 3 scripts. For example:
rebol -q script.r "foo bar" 40
If you examine system/script/args, it contains the string "foo bar 40". This is useless! Information was lost. I need to know that "foo bar" was the first argument and 40 was the second. If I examine system/options/args, I get the following block: ["foo" "bar" "40"]. Again, useless! Information was lost.
I suspect that the solution to this is to use argument delimiters of some kind, e.g.,
rebol -q script.r 'foo bar' -n 40
This could easily be handled by PARSE, but I still don't like it. It shouldn't be terribly difficult for system/options/args to contain one string per passed argument.
REBOL's a pleasure to use, and this is the first thing I've found with which I was really disappointed. :(

In REBOL 3, the behaviour you observe is a known bug.
(At the moment, R3 internally passes args from the OS to scripts as a single string, concatenating all original arguments in the process. Currently this process is not fully reversible, which is the cause of this bug. R3 probably should_ pass arguments as a list of strings instead, effectively preserving the original argv but stripped of arguments used by the interpreter itself.)
In REBOL 2, system/options/args is safer to use for command-line arguments, whereas system/script/args can be used to pass values between REBOL scripts more directly. I assume that similar behaviour will be kept for R3.
Here's a quick script to inspect argument parsing behaviour:
REBOL []
print system/version
print "options args:"
probe system/options/args
print "script args:"
probe system/script/args
REBOL 2, on OSX:
2.7.7.2.5
options args:
["foo bar" "40"]
script args:
"foo bar 40"
REBOL 3, on OSX:
2.100.111.2.5
options args:
["foo" "bar" "40"]
script args:
"foo bar 40"

You can escape the quotes:
rebol -q script.r \"foo bar\" 40
Don't know if this is a shortcoming of shell or REBOL?

Related

How to explore a namespace in gnu smalltalk

When using gnu smalltalk (without emacs integration) what commands/process does one use to explore the contents of a namespace ? For example, I want to find out how to use the contents of NetClients but if I just type
NetClients examine
I get an enormous amount of text scrolling past. Is it even possible to pass this into something like less so I can scroll back and forth through it ? Ideally I'd like to see a list of classes for example, along with their general description. Then for those classes I'd like to be able to see only their selectors.
If you want to search in the text output when sending messages, I would simply redirect the output to file.
I would do the following:
gst -a > netclients_namespace.txt
type: NetClients examine
check the netclients_nemespace.txt file where you will have the output of the messages. You can check it while the gst is still running
If you are done just break it via ctrl+c
Explaining:
-a --smalltalk-args Pass the remaining arguments to Smalltalk.
Allows you to type in the messages and get the output redirected.
Edit: (missed that question about classes at Namespace)
That being said I'm not big fan of GNU Smalltalk as I don't like the CLI only interface in supports. I think the biggest advantage of Smalltalk from the beginning was its GUI support and if you need it you can use CLI if the Smalltalk environment you are using is supporting it like Smalltalk/X-jv.
Usually inspect is the keyword used in Smalltalk instead of examine. Which will give you an internal view of an object.
If you want to list classes at Namespace you could do it the following way:
NetClients do: [ :namespaceDetail |
namespaceDetail isClass ifTrue: [ namespaceDetail printNl ]
].
To print description of the classes you could to it like this:
NetClients do: [ :namespaceDetail |
namespaceDetail isClass ifTrue: [
'--->' printNl. namespaceDetail printNl. '<---' printNl.
namespaceDetail comment printNl
]
].
In similar fashion you would get selectors.

How do I escape a "$" in bitbake/yocto?

One of my recipes in Yocto need to create a file containing a very specific line, something like:
${libdir}/something
To do this, I have the recipe task:
do_install() {
echo '${libdir}/something' >/path/to/my/file
}
Keeping in mind that I want that string exactly as shown, I can't figure out how to escape it to prevent bitbake from substituting in its own value of libdir.
I originally thought the echo command with single quotes would do the trick (as it does in the bash shell) but bitbake must be interpreting the line before passing it to the shell. I've also tried escaping it both with $$ and \$ to no avail.
I can find nothing in the bitbake doco about preventing variable expansion, just stuff to do with immediate, deferred and Python expansions.
What do I need to do to get that string into the file as is?
Bitbake seems to have particular issues in preventing expansion from taking place. Regardless of whether you use single or double quotes, it appears that the variables will be expanded before being passed to the shell.
Hence, if you want them to not be expanded, you need to effectively hide them from BitBake, and this can be done with something like:
echo -e '\x24{libdir}/something' >/path/to/my/file
This uses the hexadecimal version of $ so that BitBake does not recognise it as a variable to be expanded.
You do need to ensure you're running the correct echo command however. Under some distros (like Ubuntu), it might run the sh-internal echo which does not recognise the -e option. In order to get around that, you may have to run the variant of echo that lives on the file system (and that does recognise that option):
/bin/echo -e '\x24{libdir}/something' >/path/to/my/file
By default this task will be executed as shell function via /bin/sh, but it depends on your system what it will be as you can have a symlink named /bin/sh pointing to bash. The BitBake's manual prevents from using bashism syntax though.
You can consider just adding this task in your recipe as python function:
python do_install () {
with open('/path/to/your/file', 'a') as file:
file.write('${libdir}/something')
}
'a' stands for append.
This should eliminate the problem with variable expansion.
There is no standard way to escape these sorts of expressions that I am aware of, other than to try to break up the expression - accordingly this should work:
do_install() {
echo '$''{libdir}/something' >/path/to/my/file
}
The best solution is simply this:
bitbake_function() {
command $libdir/whatever
}
Bitbake will only expand ${libdir}; $libdir is passed through verbatim.
We don't have to worry about dollar signs that are not followed by {, and in this case, there is no need for libdir to be wrapped in braces.
The only time we run into a problem with just $foo is if we have something like ${foo}bar where the braces are required as delimiters so that bar isn't included into the variable name. In that situation, there are other solutions, such as for instance generating the shell syntax "$foo"bar. This is less cryptic than resorting to \x24.
If you need to use $ in variable assignment, remember that bitbake won't evaluate $whatever so you have to escape it for the underlying shell.
For instance I set gcc/ld Rpath option to use $ORIGIN keyword this way:
TARGET_LDFLAGS_append = " -Wl,-rpath-link=\\$$ORIGIN"
https://lists.yoctoproject.org/pipermail/yocto/2017-September/037820.html
You can define a variable to be a literal dollar sign.
DOLLAR = "$"
do_install() {
echo '${DOLLAR}{libdir}/something' >/path/to/my/file
}
no extra quoting required.

How to make `-n=3` the same as `-n 3` in Perl 6?

PerlĀ 6 has great builtin command-line parsing via MAIN. However, I faced a problem which seems to be trivial, but I cannot figure it out.
A simple MAIN:
sub MAIN(Int :n(:$num)) {
say "You passed: " ~ $num;
}
Then I can call my script as:
$ ./test.p6 -n=1
or:
$ ./test.p6 --num=1
But can't with:
$ ./test.p6 -n 1 # or even -n1
or:
$ ./test.p6 --num 1
I went through the design document for MAIN with no luck. How can I make this work?
Some info:
That's a reported bug. If you discover more about this that isn't mentioned in that bug report, eg find a workaround, please consider adding a comment to the report.
For your convenience, here are the other two extant bug reports I found for MAIN: Usage does not print required type for positional params in MAIN and fail to handle numbers as option name for MAIN.
Some options:
Use an options module. Maybe Getopt::Tiny will do the trick.
Help fix #124664. Perl 6 is (mostly) written in Perl 6. I think the code that munges raw main command line args and binds them to MAIN signature variables is the 20 lines or so in process-cmd-args.

apache velocity: remap $ and # keys

I wonder if it is possible to remap "$" and "#" to other keys.
sample:
#set( $foo = "bar" )
I want to use other keys because those interfere with another syntax of a script I am using.
$ and # characters are not configurable in Velocity. Even at compile time, it would at least imply to recompile the parser, and make a full code review for standalone $ and # chars...
That said:
Velocity does cope pretty well with syntax fragments it cannot parse, like jQuery $ object. It just render them as is, and most of the time it does the job.
You can escape your other script's sensitive characters whenever needed, for instance by using the EscapeTool: ${esc.d} for dollar, ${esc.h} for hash.

How to look at image code in GNU Smalltalk?

how can I look at class / message code from within the GST command line interface?
I only know the #inspect message, but this shows only a definition or summary of the object, not the code.
Thank you :-)
You can use the "methodSourceString" method, like
st>(Object >> #printNl) methodSourceString
'printNl [
"Print a represention of the receiver on stdout, put a new line
the Transcript (stdout the GUI is not active)"
<category: ''printing''>
Transcript showCr: self printString
]'
However, the string will be printed with double quotes, which can be inconvenient for non-trivial code.
It's often simpler to just use a text editor, because almost always classes are contained in a single file. You can query the file name from the REPL, too:
st> Object methodDictionary anyOne methodSourceCode file
<File /usr/share/smalltalk/kernel/Object.st>