Skip to content

Commit 1f959a9

Browse files
committed
added Ruby Snippet node
1 parent c49a8d2 commit 1f959a9

9 files changed

Lines changed: 167 additions & 38 deletions

RubyScript/plugin.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@
4040
icon="ruby_16.png"/>
4141
</extension>
4242

43+
<extension
44+
point="org.knime.workbench.repository.nodes">
45+
<node
46+
category-path="/community/RubyScripting"
47+
factory-class="org.knime.ext.jruby.RubySnippetNodeFactory"
48+
id="org.knime.ext.jruby.RubySnippetNodeFactory"
49+
icon="ruby_snippet_16.png"/>
50+
</extension>
51+
4352
<extension
4453
point="org.eclipse.ui.preferencePages">
4554
<page

RubyScript/rb/knime.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ def to_i; getIntValue(); end
5151
# convert to long
5252
def to_l; getLongValue(); end
5353
end
54+
55+
def snippetRunner
56+
count, step = $inData0.length, 0x2FF
57+
coef = step/count.to_f
58+
$inData0.each_with_index do |row,i|
59+
$outContainer0 << (yield row)
60+
setProgress "#{i*coef}%" if (i & step) == 0
61+
end
62+
end
5463
end
5564
include Knime
5665

RubyScript/src/org/knime/ext/jruby/RubyScriptNodeFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class RubyScriptNodeFactory extends NodeFactory<RubyScriptNodeModel> {
1717
*/
1818
@Override
1919
public RubyScriptNodeModel createNodeModel() {
20-
return new RubyScriptNodeModel(1, 1);
20+
return new RubyScriptNodeModel(1, 1, false);
2121
}
2222

2323
/**

RubyScript/src/org/knime/ext/jruby/RubyScriptNodeFactory01.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public class RubyScriptNodeFactory01 extends RubyScriptNodeFactory {
1313
*/
1414
@Override
1515
public final RubyScriptNodeModel createNodeModel() {
16-
return new RubyScriptNodeModel(0, 1);
16+
return new RubyScriptNodeModel(0, 1, false);
1717
}
1818
}

RubyScript/src/org/knime/ext/jruby/RubyScriptNodeFactory22.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public class RubyScriptNodeFactory22 extends RubyScriptNodeFactory {
1313
*/
1414
@Override
1515
public final RubyScriptNodeModel createNodeModel() {
16-
return new RubyScriptNodeModel(2, 2);
16+
return new RubyScriptNodeModel(2, 2, false);
1717
}
1818
}

RubyScript/src/org/knime/ext/jruby/RubyScriptNodeModel.java

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,33 @@ public class RubyScriptNodeModel extends NodeModel {
6161
protected String scriptHeader = "";
6262
protected String scriptFooter = "";
6363
protected String script = "";
64+
protected int scriptFirstLineNumber;
65+
6466
protected boolean appendCols = true;
6567
protected String[] columnNames;
6668
protected String[] columnTypes;
6769
private static String javaExtDirsExtensionsPath;
6870
private static String javaClasspathExtensionsPath;
71+
72+
private boolean snippetMode;
6973

70-
protected RubyScriptNodeModel(int inNumInputs, int inNumOutputs) {
74+
protected RubyScriptNodeModel(int inNumInputs, int inNumOutputs, boolean snippetMode) {
7175
super(inNumInputs, inNumOutputs);
7276

7377
this.numInputs = inNumInputs;
7478
this.numOutputs = inNumOutputs;
79+
this.snippetMode = snippetMode;
7580

7681
// define the common imports string
7782
StringBuffer buffer = new StringBuffer();
7883
buffer.append("require PLUGIN_PATH+'/rb/knime.rb'\n");
84+
scriptFirstLineNumber = 2;
85+
86+
if (this.snippetMode == true ) {
87+
buffer.append("func = ->(row) do \n");
88+
scriptFirstLineNumber += 1;
89+
}
90+
7991
scriptHeader = buffer.toString();
8092

8193
buffer = new StringBuffer();
@@ -84,42 +96,73 @@ protected RubyScriptNodeModel(int inNumInputs, int inNumOutputs) {
8496
buffer.append(String.format(
8597
"# inData%d - input DataTable %d\n", i, i + 1));
8698
}
99+
buffer.append("# outContainer - container housing output DataTable"
100+
+ " (the same as outContainer0)\n");
87101

88-
if (numInputs > 0) {
89-
buffer.append("# outContainer - container housing output DataTable\n");
90-
buffer.append("#\n");
91-
buffer.append("# Example starter script. Add values for new two columns with String and Int types:\n");
92-
buffer.append("#\n");
93-
buffer.append("# count = $inData0.length\n");
94-
buffer.append("# $inData0.each_with_index do |row, i|\n");
95-
buffer.append("# $outContainer << row << (Cells.new.string('Hi!').int(row.getCell(0).to_s.length))\n");
96-
buffer.append("# setProgress \"#{i*100/count}%\" if i%100 != 0\n");
97-
buffer.append("# end\n");
98-
buffer.append("#\n");
99-
buffer.append("# Default script:\n");
100-
buffer.append("#\n\n");
101-
buffer.append("$inData0.each do |row|\n");
102-
buffer.append(" $outContainer << row\n");
103-
buffer.append("end");
104-
} else {
105-
buffer.append("# outContainer - container housing output DataTable\n");
106-
buffer.append("#\n");
107-
buffer.append("# Example starter script. Add values for new two columns with String and Int types:\n");
108-
buffer.append("#\n");
109-
buffer.append("# count = 100000\n");
110-
buffer.append("# count.times do |i|\n");
111-
buffer.append("# $outContainer << Cells.new.string('Hi!').int(rand i))\n");
112-
buffer.append("# setProgress \"#{i*100/count}%\" if i%100 != 0\n");
113-
buffer.append("# end\n");
114-
buffer.append("#\n");
115-
buffer.append("# Default script:\n");
102+
for (int i = 0; i < numOutputs; i++) {
103+
buffer.append(String
104+
.format("# outContainer%d - container housing output DataTable %d\n", i, i+1));
105+
}
106+
buffer.append("#\n");
107+
108+
if (this.snippetMode) {
109+
buffer.append("# Snippet intended for operations with one row.\n"
110+
+ "# This code places in the special lambda function with argument named row.\n"
111+
+ "# The lambda function must return the row by any available for Ruby ways.\n"
112+
+ "#\n"
113+
+ "# Example script. "
114+
+ "Add new two columns with String and Int types from current row:\n"
115+
+ "# row << (Cells.new.string('Hi!').int(row.getCell(0).to_s.length))\n"
116+
+ "#\n");
117+
118+
buffer.append("# Default snippet (copy existing row):\n");
116119
buffer.append("#\n\n");
117120

118-
buffer.append("10.times do |i|\n");
119-
buffer.append(" $outContainer << Cells.new.int(i)\n");
120-
buffer.append("end");
121+
buffer.append(" row");
122+
123+
} else {
124+
if (numInputs > 0) {
125+
buffer.append("# Example starter script. "
126+
+ "Add values for new two columns with String and Int types:\n"
127+
+ "#\n"
128+
+ "# count = $inData0.length\n"
129+
+ "# $inData0.each_with_index do |row, i|\n"
130+
+ "# $outContainer << "
131+
+ "row << (Cells.new.string('Hi!').int(row.getCell(0).to_s.length))\n"
132+
+ "# setProgress \"#{i*100/count}%\" if i%100 != 0\n"
133+
+ "# end\n" + "#\n");
134+
buffer.append("# Default script:\n");
135+
buffer.append("#\n\n");
136+
137+
buffer.append("$inData0.each do |row|\n");
138+
buffer.append(" $outContainer << row\n");
139+
buffer.append("end");
140+
} else {
141+
buffer.append("# Example starter script. " +
142+
"Add values for new two columns with String and Int types:\n");
143+
buffer.append("#\n");
144+
buffer.append("# count = 100000\n");
145+
buffer.append("# count.times do |i|\n");
146+
buffer.append("# $outContainer << Cells.new.string('Hi!').int(rand i))\n");
147+
buffer.append("# setProgress \"#{i*100/count}%\" if i%100 != 0\n");
148+
buffer.append("# end\n");
149+
buffer.append("#\n");
150+
buffer.append("# Default script:\n");
151+
buffer.append("#\n\n");
152+
153+
buffer.append("10.times do |i|\n");
154+
buffer.append(" $outContainer << Cells.new.int(i)\n");
155+
buffer.append("end");
156+
}
121157
}
122158
script = buffer.toString();
159+
160+
if (this.snippetMode) {
161+
buffer = new StringBuffer();
162+
buffer.append("end\n");
163+
buffer.append("snippetRunner &func\n");
164+
scriptFooter = buffer.toString();
165+
}
123166
}
124167

125168
protected final BufferedDataTable[] execute(final BufferedDataTable[] inData,
@@ -227,8 +270,8 @@ protected final BufferedDataTable[] execute(final BufferedDataTable[] inData,
227270
container.put("$exec", exec);
228271
container.put("PLUGIN_PATH", rubyPluginPath);
229272

230-
EvalUnit unit = container
231-
.parse(scriptHeader + script + scriptFooter, 1);
273+
EvalUnit unit = container.parse(scriptHeader + script + scriptFooter,
274+
scriptFirstLineNumber);
232275
unit.run();
233276

234277
BufferedDataTable[] result = new BufferedDataTable[numOutputs];
@@ -353,5 +396,5 @@ public static void setJavaClasspathExtensionPath(String path) {
353396

354397
public static String getJavaClasspathExtensionPath() {
355398
return javaClasspathExtensionsPath;
356-
}
399+
}
357400
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.knime.ext.jruby;
2+
3+
/**
4+
* <code>NodeFactory</code> for the "RubyScript" Node.
5+
*
6+
*
7+
* @author
8+
*/
9+
public class RubySnippetNodeFactory extends RubyScriptNodeFactory {
10+
11+
/**
12+
* {@inheritDoc}
13+
*/
14+
@Override
15+
public final RubyScriptNodeModel createNodeModel() {
16+
return new RubyScriptNodeModel(1, 1, true);
17+
}
18+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<knimeNode icon="./ruby_snippet_16.png" type="Manipulator" xmlns="http://knime.org/node/v2.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://knime.org/node/v2.8 http://knime.org/node/v2.8.xsd">
3+
<name>Ruby Snippet</name>
4+
5+
<shortDescription>
6+
This package implements Ruby scripts.
7+
8+
Currently employs jRuby v1.7.9 with Ruby 2.0 syntax.
9+
</shortDescription>
10+
11+
<fullDescription>
12+
<intro>Executes a small jRuby script. The main difference between this node and Ruby Script is that it operates with each row of input DataTable separately and returns a new row for output DataTable. A simple example script is included in the dialog's text window of the Script tab.
13+
<p>This node uses Ruby-wrapper. See knime.rb at <a href="https://github.com/rssdev10/ruby4knime">ruby4knime</a></p>
14+
15+
<p>Also you can include additional gems from an external jRuby installation. But before setup jRuby path in preferences.</p>
16+
17+
</intro>
18+
19+
<tab name="Script output">
20+
<option name="Append columns to input table spec">If checked, the columns as given in the list are appended to the input table specification, i.e. the number of columns in the output table equals the number of input columns plus the number of columns as given in the list. If unchecked, the output table will have as many columns as given in the list.</option>
21+
<option name="Column list">Specify the column name and type of all result columns. After adding a new column, click on the name or type to change its value.</option>
22+
</tab>
23+
24+
<tab name="Script">
25+
<option name="$inData0">The input DataTable containing all available input from input port 0.</option>
26+
<option name="$outContainer">Output container housing the outgoing DataTable for output port 0. This must be populated with rows by the script or else there will be no output from the node.</option>
27+
28+
<option name="row">Current row of input DataTable.</option>
29+
30+
<option name="Example use to copy all input rows of DataTable:"><pre>
31+
row # Only row!
32+
</pre></option>
33+
<option name="Example use to extend input rows by new columns:"><pre>
34+
row &lt;&lt; Cells.new.string('Hi!').int(row[0].to_s.length))
35+
</pre></option>
36+
37+
<option name="Example use to create new DataTable from custom columns"><pre>
38+
Cells.new.double(row[0].to_f).double(row[2].to_f - row[1].to_f)
39+
</pre></option>
40+
</tab>
41+
</fullDescription>
42+
43+
<ports>
44+
<inPort index="0" name="In-Port name">Table that the Ruby script will operate on.</inPort>
45+
<!-- possibly more input ports here-->
46+
<outPort index="0" name="Out-Port name">Table containing the results of the Ruby script.</outPort>
47+
<!-- possibly more output ports here-->
48+
</ports>
49+
</knimeNode>
50+
500 Bytes
Loading

0 commit comments

Comments
 (0)