CoffeeScript: Spurious comma in comprehension joined by empty separator - coffeescript

I wanted a convenience function to catenate jQuery parent > child selector strings. I can't get the following to work in CS 1.10.0 (also tested in 1.7.1). What am I doing wrong?
pcsel = (parent_sel, child_sels...) ->
### Uitlity for forming parent > child selector string ###
childchain = [" > " + child for child in child_sels]
parent_sel + childchain.join('')
console.log pcsel("foo", "bar") # OK. yields "foo > bar"
console.log pcsel("foo", "bar", "glop") # BAD. yields "foo > bar, > glop"
# Sanity check
console.log "foo" + [" > bat", " > glop"].join('') # OK. yields "foo > bar > glop"
Thanks!
(I've also posted this as an issue in the CS repository)

A loop comprehension:
expr for e in array
evaluates to an array. That means that this:
[ expr for e in array ]
is actually a single element array whose first (and only) element is the array from the loop. More explicitly:
i for i in [1,2,3]
is [1,2,3] but this:
[ i for i in [1,2,3] ]
is [[1,2,3]].
Your problem is that childchain in pcsel ends up with an extra level of nesting and the stringification from the join call adds unexpected commas.
The solution is to fix pcsel:
childchain = (" > " + child for child in child_sels)
# -----------^-------------------------------------^
You need the parentheses (not brackets) to get around precedence issues; parentheses (()) and brackets ([]) serve entirely different functions so you need to use the right ones.

From what I can tell, the behavior you're seeing is what's to be expected. Here's how your code behaves if you replace the splat with an explicit array:
coffee> ["> " + ['bar']] # => ['> bar']
coffee> ["> " + ['bar', 'baz']] # =>['> bar,baz']
You'll also see the same behavior in node:
> [">" + ['bar']] // => ['>bar']
> ["> " + ['bar', 'baz']] // => ['> bar,baz']
You could achieve what you're after using multiple calls to .join, or by doing something like this:
pcsel = (parent_sel, child_sels...) ->
child_sels.reduce (memo, sel) ->
memo + " > #{sel}"
, parent_sel
console.log pcsel("foo", "bar") # => foo > bar
console.log pcsel("foo", "bar", "glop") # => foo > bar > glop
console.log pcsel("foo", "bar", "glop", "baz") # => foo > bar > glop > baz

Related

erlang macro expansion bug

macro module:
-module(macro).
-include_lib("eunit/include/eunit.hrl").
-define(EXPAND(_T), ??_T).
macro_test() ->
?assertEqual("Test", ?EXPAND(Test)),
?assertEqual("Test.test", ?EXPAND(Test.test)).
Is resulting :
6> c(macro).
{ok,macro}
7> eunit:test(macro).
macro: macro_test (module 'macro')...*failed*
in function macro:'-macro_test/0-fun-1-'/1 (macro.erl, line 9)
**error:{assertEqual_failed,[{module,macro},
{line,9},
{expression,"? EXPAND ( Test . test )"},
{expected,"Test.test"},
{value,"Test . test"}]}
=======================================================
Failed: 1. Skipped: 0. Passed: 0.
error
Am I doing something wrong or is this a known bug?
TIA
You're incorrectly assuming that the Erlang compiler treats Test.test as a single token. If you pass the -P option to erlc and examine the output, you'll see that the preprocessor breaks it into multiple tokens. Here's the interesting part of macro.P produced by erlc -P macro.erl:
macro_test() ->
begin
fun(__X) ->
case "Test" of
__X ->
ok;
__V ->
error({assertEqual,
[{module,macro},
{line,8},
{expression,"? EXPAND ( Test )"},
{expected,__X},
{value,__V}]})
end
end("Test")
end,
begin
fun(__X) ->
case "Test . test" of
__X ->
ok;
__V ->
error({assertEqual,
[{module,macro},
{line,9},
{expression,"? EXPAND ( Test . test )"},
{expected,__X},
{value,__V}]})
end
end("Test.test")
end.

Advanced Command-Line Replace Command In VBScript

I'm writing a compiler for my won computer language. Now before the language can be compiled i actually need to replace all apostrophes (') with percents (%) via a command-line vbs program. But the apostrophes only need to be replaced if there is NOT a circumflex accent (^) in front of it. So for example, in this code:
color 0a
input twelve = 0a "hi! that^'s great! "
execute :testfornum 'twelve'
exit
:testfornum
if numeric('1) (
return
) ELSE (
print 0a "oops 'twelve' should be numeric"
)
return
the apostrophe at line 2 should not be replaced, but the ones at line 3, 6 and 9 should be.
can anyone help me?
this is what i have so far:
'syntax: (cscript) replace.vbs [filename] "StringToFind" "stringToReplace"
Option Explicit
Dim FileScriptingObject, file, strReplace, strReplacement, fileD, lastContainment, newContainment
file=Wscript.arguments(0)
strReplace=WScript.arguments(1)
strReplacement=WScript.arguments(2)
Set FileScriptingObject=CreateObject("Scripting.FileSystemObject")
if FileScriptingObject.FileExists(file) = false then
wscript.echo "File not found!"
wscript.Quit
end if
set fileD=fileScriptingobject.OpenTextFile(file,1)
lastContainment=fileD.ReadAll
newContainment=replace(lastContainment,strReplace,strReplacement,1,-1,0)
set fileD=fileScriptingobject.OpenTextFile(file,2)
fileD.Write newContainment
fileD.Close
As #Ansgar's solution fails for the special case of a leading ' (no non-^ before that), here is an approach that uses a replace function in a test script that makes further experiments easy:
Option Explicit
Function fpR(m, g1, g2, p, s)
If "" = g1 Then
fpR = "%"
Else
fpR = m
End If
End Function
Function qq(s)
qq = """" & s & """"
End Function
Dim rE : Set rE = New RegExp
rE.Global = True
rE.Pattern = "(\^)?(')"
Dim rA : Set rA = New RegExp
rA.Global = True
rA.Pattern = "([^^])'"
'rA.Pattern = "([^^])?'"
Dim s
For Each s In Split(" 'a^'b' a'b'^'c nix a^''b")
WScript.Echo qq(s), "==>", qq(rE.Replace(s, GetRef("fpR"))), "==>", qq(rA.Replace(s, "$1%"))
Next
output:
cscript 25221565.vbs
"" ==> "" ==> ""
"'a^'b'" ==> "%a^'b%" ==> "'a^'b%" <=== oops
"a'b'^'c" ==> "a%b%^'c" ==> "a%b%^'c"
"nix" ==> "nix" ==> "nix"
"a^''b" ==> "a^'%b" ==> "a^'%b"
You can't do this with a normal string replacement. A regular expression would work, though:
...
Set re = New RegExp
re.Pattern = "(^|[^^])'"
re.Global = True
newContainment = re.Replace(lastContainment, "$1%")
...

Scripting with Scala: How to launch an uncompiled script?

Apart from serious performance problems, Scala is a very powerful language. Therefore I am now using it frequently for scripted tasks inside Bash. Is there a way to just execute a *.scala file exactly the way I can do with Python files? As far as I know, Python uses bytecode to execute programs, exactly like the JVM does. However, there is not anything called pythonc (like scalac or javac) I need to call in order to accomplish this. Hence I expect Scala to be able to act in a similar manner.
The scala man page provides some examples on how to run Scala code fragments as if they were a script, for both Windows and non-Windows platforms (below examples copied from the man page):
Unix
#!/bin/sh
exec scala "$0" "$#"
!#
Console.println("Hello, world!")
argv.toList foreach Console.println
Windows
::#!
#echo off
call scala %0 %*
goto :eof
::!#
Console.println("Hello, world!")
argv.toList foreach Console.println
To speed up subsequent runs you can cache the compiled fragment with the -savecompiled option:
#!/bin/sh
exec scala -savecompiled "$0" "$#"
!#
Console.println("Hello, world!")
argv.toList foreach Console.println
Update: as of Scala 2.11 (as noted in this similar answer), you can now just do this on Unix:
#!/usr/bin/env scala
println("Hello, world!")
println(args.mkString(" "))
I don't use python, but in Scala, the most scripty thing I can do is this:
thinkpux:~/proj/mini/forum > echo 'println(" 3 + 4 = " + (3 + 4))' | scala
Welcome to Scala version 2.10.2 (Java HotSpot(TM) Server VM, Java 1.7.0_09).
Type in expressions to have them evaluated.
Type :help for more information.
scala> println(" 3 + 4 = " + (3 + 4))
3 + 4 = 7
scala> thinkpux:~/proj/mini/forum >
However, afterwards, I don't have visual feedback in the bash, so I have to call 'clear'.
But there is no problem in writing a script and executing that:
thinkpux:~/proj/mini/forum > echo 'println(" 3 + 4 = " + (3 + 4))' > print7.scala
thinkpux:~/proj/mini/forum > scala print7.scala
3 + 4 = 7
Then, there aren't issues with the shell.
With an enclosing class, the code wouldn't be executed:
thinkpux:~/proj/mini/forum > echo -e 'class Foo {\nprintln(" 3 + 4 = " + (3 + 4))\n}\n'
class Foo {
println(" 3 + 4 = " + (3 + 4))
}
thinkpux:~/proj/mini/forum > scala Foo.scala
thinkpux:~/proj/mini/forum > cat Foo.scala
class Foo {
println(" 3 + 4 = " + (3 + 4))
}
But with instatiating a class, you can execute code in it, without using the wellknown (hope so) 'main' way:
thinkpux:~/proj/mini/forum > echo -e 'class Foo {\nprintln(" 3 + 4 = " + (3 + 4))\n}\nval foo = new Foo()' > Foo.scala
thinkpux:~/proj/mini/forum > cat Foo.scala
class Foo {
println(" 3 + 4 = " + (3 + 4))
}
val foo = new Foo()
thinkpux:~/proj/mini/forum > scala Foo.scala
3 + 4 = 7

Tree::Simple::traverse() is not visiting root of tree - error or feature ?

if I try the following code
#!/usr/bin/env perl
use Tree::Simple;
# Tree:
# a
# _________ | ________
# / | \
# b c d
# / \
# e f
# \
# g
#
my $tree = Tree::Simple->new('a', Tree::Simple->ROOT);
$tree->addChildren( Tree::Simple->new('b'),
Tree::Simple->new('c'),
Tree::Simple->new('d'),
);
$tree->getChild(1)->addChildren (
Tree::Simple->new('e'),
Tree::Simple->new('f'),
);
$tree->getChild(1)->getChild(1)->addChildren (
Tree::Simple->new('g'),
);
$trav_func= sub {
my $node = shift;
printf "node : %s leaf : %3s root : %s\n",
$node->getNodeValue, $node->isLeaf ? 'yes' : 'no',
$node->isRoot ? 'yes' : 'no';
};
# traversal does not report the root - error ?
print "------ preorder : traverse( \$trav_func ) \n";
$tree->traverse( $trav_func );
print "\n";
print "------ postorder : traverse( sub{}, \$trav_func ) \n";
$tree->traverse( sub{}, $trav_func );
print "\n";
the output is
------ preorder : traverse( $trav_func )
node : b leaf : yes root : no
node : c leaf : no root : no
node : e leaf : yes root : no
node : f leaf : no root : no
node : g leaf : yes root : no
node : d leaf : yes root : no
------ postorder : traverse( sub{}, $trav_func )
node : b leaf : yes root : no
node : e leaf : yes root : no
node : g leaf : yes root : no
node : f leaf : no root : no
node : c leaf : no root : no
node : d leaf : yes root : no
showing that root 'a' is not visited. My understanding of tree traversal is that all nodes should be visited. Am I wrong or are there some cases where it makes sense not to visit the root ?
Appendix :
Tree::Simple::traverse() is implemented as :
sub traverse {
my ($self, $func, $post) = #_;
# ... some checks here not shown
foreach my $child ($self->getAllChildren()) {
$func->($child);
$child->traverse($func, $post);
defined($post) && $post->($child);
}
}
For the first node (root) $func/$post are not called, so there is no visit for it.
If you override traverse() with
package My::Tree::Simple;
use parent 'Tree::Simple';
# the original code of Tree::Simple::traverse()
# but $func() and $post() outside of foreach-loop
# allowing the root to be visited
sub my_traverse {
my ($self, $func, $post) = #_;
(defined($func)) || die "Insufficient Arguments : Cannot traverse without traversal function";
(ref($func) eq "CODE") || die "Incorrect Object Type : traversal function is not a function";
(ref($post) eq "CODE") || die "Incorrect Object Type : post traversal function is not a function"
if defined($post);
$func->($self); # put outside of foreach
foreach my $child ($self->getAllChildren()) {
$child->my_traverse($func, $post);
}
defined($post) && $post->($self); # put outside of foreach
}
it works as I expected.
I've been recently using the Tree::Simple package and I think that the observed behavior is consistent with the documentation. Consider, for example, the 'getDepth' function. In the documentation it says:
getDepth
Returns a number representing the invocant's depth within the
hierarchy of Tree::Simple objects.
NOTE: A ROOT tree has the depth of -1. This be because Tree::Simple
assumes that a tree's root will usually not contain data, but just be
an anchor for the data-containing branches. This may not be intuitive
in all cases, so I mention it here.
From this, it seems to me that you need and "anchor" that must not contain data. In other words, your tree should look like this:
# Tree:
# anchor
# |
# a
# _________ | ________
# / | \
# b c d
# / \
# e f
# \
# g
#
Then, the 'anchor' will be depth -1, 'a' will be depth 0, and 'b', 'c', 'd' will be depth 1.
Hope this helps.
You are right. The root should be included in a tree traversal. This is especially clear if you try an inorder traversal, since (considering your root has two children) the root should be inbetween the two children. Google it, you'll see the same behavior everywhere. I even checked my book on algorithms.
I'd make sure i have the newest version of the module, and report it as an error.
So, I agree with all the posters here, that this can be a little confusing. However, the module is well establish and is currently being used in a number of places/codebases so a radical behavior change like changing how \&traverse works is not something I would entertain.
That said, it was my view at the time (and kind of still is), that there is a difference between traversal (implemented with the \&traverse method) and visitation. If you take a look at the Tree::Simple::Visitor module, you will be able to accomplish exactly what you are are after by setting the \&includeTrunk method accordingly. Additionally there are a number of other visitor implementations in that module that you might find useful.
I would also encourage you to take a look at the Forest module, which is a modern re-write of Tree::Simple that uses Moose . It too has a \&traverse method which behaves in this way, but it also has a \&fmap_cont method which is much more powerful. Additionally Forest has support for immutable (pure) trees as well as default reader/writer classes for serializing/deserializing your trees, indexing your trees, JSON serialization and more.

What cmdlets use the IHostUISupportsMultipleChoiceSelection interface to prompt for choices?

I don't remember ever being prompted for multiple selections before in PowerShell, but I've seen several examples of hosts implementing this interface. Unfortunately, those are the only references I've seen to the interface. I've never seen "here's how to test that you're implementing it correctly".
Please, disregard my first answer; it is not an answer at all, as I can see now. And thank you for a really interesting question.
I still do not know cmdlets that use that interface. But we can use it on our own from scripts. Let's modify the mentioned Get-Choice.ps1 and call the new one Get-Choice2.ps1:
<#
.SYNOPSIS
Displays PowerShell style menu and gets user choices
.DESCRIPTION
*) Returns choice indexes.
*) Choice keys are indicated by '&' in menu items.
*) Help strings can be empty or nulls (items are used themselves).
#>
param
(
# Menu caption
[string]$Caption = 'Confirm',
# Menu message
[string]$Message = 'Are you sure you want to continue?',
# Choice info pairs: item1, help1, item2, help2, ...
[string[]]$Choices = ('&Yes', 'Continue', '&No', 'Stop'),
# Default choice indexes (i.e. selected on [Enter])
[int[]]$DefaultChoice = #(0)
)
if ($args) { throw "Unknown parameters: $args" }
if ($Choices.Count % 2) { throw "Choice count must be even." }
$descriptions = #()
for($i = 0; $i -lt $Choices.Count; $i += 2) {
$c = [System.Management.Automation.Host.ChoiceDescription]$Choices[$i]
$c.HelpMessage = $Choices[$i + 1]
if (!$c.HelpMessage) {
$c.HelpMessage = $Choices[$i].Replace('&', '')
}
$descriptions += $c
}
$Host.UI.PromptForChoice($Caption, $Message, [System.Management.Automation.Host.ChoiceDescription[]]$descriptions, $DefaultChoice)
Now we test it:
Get-Choice2 'Title' 'Message' -DefaultChoice 0, 1, 2 -Choices #(
'Choice &1', 'This is choice 1'
'Choice &2', ''
'Choice &3', ''
'Choice &4', ''
'Choice &5', ''
'Choice &6', ''
'Choice &7', ''
'Choice &8', ''
'Choice &9', ''
'Choice &0', ''
)
It prints 10 choices, the first 3 are highlighted (in the console host), and prompts:
0> Test-Get-Choice2.ps1
Title
Message
[1] Choice 1
[2] Choice 2
[3] Choice 3
[4] Choice 4
[5] Choice 5
[6] Choice 6
[7] Choice 7
[8] Choice 8
[9] Choice 9
[0] Choice 0
[?] Help
(default choices are 1,2,3)
Choice[0]:
If we press Enter immediately the output is the default 3 indexes: 0, 1, 2. If we type, for example: 5 + Enter + 3 + Enter + 1 + Enter + Enter then the output is 4, 2, 0.
It works. PowerShell ISE also supports this but the UI might be something better in GUI version, perhaps.
For example: the command Remove-Item C:\TEMP\Test prompts you to choose:
Confirm
The item at C:\TEMP\Test has children and the Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Or you can build your own call using this script (or its idea):
Get-Choice.ps1 - Displays PowerShell style menu and gets a user choice