From: <jfa...@us...> - 2011-06-25 23:51:16
|
Revision: 7012 http://oorexx.svn.sourceforge.net/oorexx/?rev=7012&view=rev Author: jfaucher Date: 2011-06-25 23:51:09 +0000 (Sat, 25 Jun 2011) Log Message: ----------- More work on pipe. Modified Paths: -------------- sandbox/jlf/_diary.txt sandbox/jlf/samples/pipeline/pipe.rex sandbox/jlf/samples/pipeline/pipe_extension.cls sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt sandbox/jlf/samples/pipeline/pipe_extension_test.rex sandbox/jlf/samples/pipeline/pipe_readme.txt Modified: sandbox/jlf/_diary.txt =================================================================== --- sandbox/jlf/_diary.txt 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/_diary.txt 2011-06-25 23:51:09 UTC (rev 7012) @@ -43,6 +43,27 @@ =============================================================================== +2011 june 25 + +More work on pipe. + +.inject : added options 'append', 'pushIndex'. +The option 'recursive' has two new sub-options : 'depthFirst', 'breadthFirst'. + +.fileTree : new pipeStage +Get the childrens (files or directories) of a file instance. + +.fileText : new pipeStage +Get the contents of a text file line by line. + +.words : new pipeStage +Get the words of the current value. + +.characters : new pipeStage +Get the characters of the current value. + + +=============================================================================== 2011 june 20 More work on pipe. Modified: sandbox/jlf/samples/pipeline/pipe.rex =================================================================== --- sandbox/jlf/samples/pipeline/pipe.rex 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/samples/pipeline/pipe.rex 2011-06-25 23:51:09 UTC (rev 7012) @@ -887,6 +887,7 @@ /******************************************************************************/ ::class displayer subclass pipeStage public +::constant indexSeparator "|" ::method init expose items context @@ -937,8 +938,8 @@ ::method displayIndex use strict arg width, value, index -if width == -1 then .output~charout(index~tostring(, ".")) - else .output~charout(index~tostring(, ".")~left(width)) +if width == -1 then .output~charout(index~tostring(, self~indexSeparator)) + else .output~charout(index~tostring(, self~indexSeparator)~left(width)) ::method displayValue use strict arg width, value, index @@ -962,7 +963,7 @@ expose actions use strict arg value, index -- get the data value if actions~items == 0 then do - say index~tostring(, ".") ":" value -- default display + say index~tostring(, self~indexSeparator) ":" value -- default display end else do do action over actions -- do each action @@ -1369,3 +1370,61 @@ stage~process(value, index) end forward message ("checkEOP") arguments (stages) + + +/******************************************************************************/ +-- A fileText pipeStage to get the contents of the file line by line. +-- The input value can be a string (used as a path) or a .File instance. +::class fileText public subclass pipeStage + +::method process +use strict arg value, index +if \value~isA(.File) then value = .File~new(value~string) +stream = .Stream~new(value~absolutePath) +signal on notready +stream~open("read") +linepos = 1 +do while self~next <> .nil, \self~next~isEOP + linetext = stream~linein + newindex = index~copy + newindex~append(value~absolutePath) + newindex~append(linepos) + self~write(linetext, newindex) + linepos += 1 +end +notready: +self~checkEOP(self~next) +stream~close + + +/******************************************************************************/ +-- A words pipeStage to get the words of the current value. +::class words public subclass pipeStage + +::method process +use strict arg value, index +wordpos = 1 +do word over value~string~space~makearray(" ") while self~next <> .nil, \self~next~isEOP + newindex = index~copy + newindex~append(wordpos) + self~write(word, newindex) + wordpos += 1 +end +self~checkEOP(self~next) + + +/******************************************************************************/ +-- A characters pipeStage to get the characters of the current value. +::class characters public subclass pipeStage + +::method process +use strict arg value, index +charpos = 1 +do char over value~string~makearray("") while self~next <> .nil, \self~next~isEOP + newindex = index~copy + newindex~append(charpos) + self~write(char, newindex) + charpos += 1 +end +self~checkEOP(self~next) + Modified: sandbox/jlf/samples/pipeline/pipe_extension.cls =================================================================== --- sandbox/jlf/samples/pipeline/pipe_extension.cls 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/samples/pipeline/pipe_extension.cls 2011-06-25 23:51:09 UTC (rev 7012) @@ -62,12 +62,16 @@ -- A function always return a result. The "return" instruction is automatically inserted, if missing. -- A function is not allowed to run a command. ::method makeFunctionDoer public class - use strict arg oneLinerFunction, context=.nil - if oneLinerFunction~strip <> "" then do - if oneLinerFunction~caselessPos("return ") == 0 then oneLinerFunction = "return" oneLinerFunction - oneLinerFunction = "use arg value, index;" oneLinerFunction + use strict arg doable, context=.nil + if doable~isA(.String) then do + source = doable + if source~strip <> "" then do + if source~caselessPos("return ") == 0 then source = "return" source + source = "use arg value, index;" source + end + doable = source end - doer = oneLinerFunction~doer(context) + doer = doable~doer(context) if doer~hasMethod("setSecurityManager") then doer~setSecurityManager(.CommandNotAllowed~new) -- A doer can be a message, which has not this method return doer @@ -75,15 +79,30 @@ -- An action can return optionnally a result, it's up to the user to insert the "return". -- An action can run a command, so no security restriction. ::method makeActionDoer public class - use strict arg oneLinerAction, context=.nil - if oneLinerAction~strip <> "" then do - oneLinerAction = "use arg value, index;" oneLinerAction + use strict arg doable, context=.nil + if doable~isA(.String) then do + source = doable + if source~strip <> "" then do + source = "use arg value, index;" source + end + doable = source end - doer = oneLinerAction~doer(context) + doer = doable~doer(context) return doer /******************************************************************************/ +::class CommandNotAllowed -- Security manager + +::method unknown + return 0 + +::method command + use strict arg info + raise syntax 98.948 array("Command not allowed:" info~address info~command) + + +/******************************************************************************/ -- An append pipeStage to copy items from its primary input to its primary output, -- and then invoke the supplier passed as argument and write the items produced by -- that supplier to its primary output. @@ -111,11 +130,11 @@ /******************************************************************************/ -- An inject pipeStage to inject the items produced by a supplier in the pipeline. -- The supplier is calculated for each processed value. --- The history of indexes is kept : assuming that the current value has index i, --- and the supplier produces the items (i1,v1), (i2,v2) etc... then the injected --- values will be (i.i1, v1), (i.i2, v2) etc.. --- The processed value itself is written in the pipeline before injecting the items --- produced by the supplier. +-- When using the option 'pushIndex', the history of indexes is kept : assuming +-- that the current value has index i, and the supplier produces the items (i1,v1), +-- (i2,v2) etc... then the injected values will be (i.i1, v1), (i.i2, v2) etc... +-- When using the option 'append', the processed value itself is written in the +-- pipeline before injecting the items produced by the supplier. ::class inject public subclass pipeStage ::method init @@ -125,56 +144,121 @@ forward class (super) ::method initOptions - expose recursive limit + expose recursive limit depthFirst append pushIndex recursive = .false limit = -1 + depthFirst = .true + append = .false + pushIndex = .false unknown = .array~new do a over arg(1, "a") parse var a first "." rest - if "recursive"~caselessAbbrev(first, 1) then do + if "recursive"~caselessAbbrev(first, 3) then do + -- recursive[.limit|.depthFirst|.breadthFirst]* recursive = .true - if rest <> "" then do -- recursive.limit - if rest~dataType("W") then limit = rest - else raise syntax 93.900 array("Expected a whole number after "first". in "a) + do while rest <> "" + parse var rest first "." rest + if first~dataType("W") then limit = first + else if "depthFirst"~caselessAbbrev(first, 1) then depthFirst = .true + else if "breadthFirst"~caselessAbbrev(first, 1) then depthFirst = .false + else raise syntax 93.900 array("Expected 'depthFirst' or 'breadthFirst' after "first". in "a) end end + else if "append"~caselessAbbrev(a, 1) then append = .true + else if "replace"~caselessAbbrev(a, 3) then append = .false + else if "pushIndex"~caselessAbbrev(a, 1) then pushIndex = .true else unknown~append(a) end forward class (super) arguments (unknown) -- forward the initialization to super to process the unknown options -::method process - expose doer recursive limit - use strict arg value, index, processed=(.queue~new) - self~write(value, index) +::method processDepthFirst + expose doer recursive limit pushIndex + use strict arg value, index, stack=(.queue~new) doer~do(value, index) if \ var("result") then return -- no result returned, nothing to inject if \ result~hasMethod("supplier") then result = .array~of(result) -- for convenience, accept a non-supplier result supplier = result~supplier - do while supplier~available & processed~items <> limit & \self~next~isEOP - newindex = index~copy - newindex~append(supplier~index) - if recursive then do - if processed~hasItem(supplier~item) then do - self~write(supplier~item, newindex) - return -- Stop the recursion because already processed - end - processed~push(supplier~item) - self~process(supplier~item, newindex, processed) - processed~pull - end - else self~write(supplier~item, newindex) - supplier~next + do while supplier~available & \self~next~isEOP + newindex = index + if pushIndex then do + newindex = index~copy + newindex~append(supplier~index) + end + if recursive & stack~items <> limit then do + if \ stack~hasItem(supplier~item) then do -- Recurse only if not already processed + self~write(supplier~item, newindex) + stack~push(supplier~item) + self~processDepthFirst(supplier~item, newindex, stack) + stack~pull + end + end + else self~write(supplier~item, newindex) + supplier~next end + + +::method processBreadthFirstCurrent + expose doer recursive limit pushIndex + use strict arg value, index, stack, toprocess + doer~do(value, index) + if \ var("result") then return -- no result returned, nothing to inject + if \ result~hasMethod("supplier") then result = .array~of(result) -- for convenience, accept a non-supplier result + supplier = result~supplier + do while supplier~available & \self~next~isEOP + newindex = index + if pushIndex then do + newindex = index~copy + newindex~append(supplier~index) + end + if recursive & stack~items <> limit then do + if \ stack~hasItem(supplier~item) then do -- Recurse only if not already processed + self~write(supplier~item, newindex) + stack~push(supplier~item) + toprocess~queue(supplier~item) + toprocess~queue(newindex) + toprocess~queue(stack~copy) + stack~pull + end + end + else do + self~write(supplier~item, newindex) + toprocess~queue(supplier~item) + toprocess~queue(newindex) + toprocess~queue(stack~copy) + end + supplier~next + end + + +::method processBreadthFirst + use strict arg value, index + stack = .queue~new + toprocess = .queue~new + self~processBreadthFirstCurrent(value, index, stack, toprocess) + do while \toprocess~isEmpty + supplier_item = toprocess~pull + newindex = toprocess~pull + stack = toprocess~pull + self~processBreadthFirstCurrent(supplier_item, newindex, stack, toprocess) + end + + +::method process + expose depthFirst append + use strict arg value, index + if append then self~write(value, index) + if depthFirst then self~processDepthFirst(value, index) + else self~processBreadthFirst(value, index) self~checkEOP(self~next) /******************************************************************************/ --- a do pipeStage to execute an action passed as argument. +-- A do pipeStage to execute an action passed as argument. -- CAREFULL ! There is NO automatic insertion of the "return" instruction, and -- the commands are authorized here, so DON'T FORGET the "return" instruction -- if you want to return a value !!!! -- Ex : assuming value==10 --- .do[2*value] will not insert 20 in the pipeline, but will instead run the command "20". +-- .do["2*value"] will not insert 20 in the pipeline, but will instead run the command "20". ::class do public subclass pipeStage ::method init @@ -193,7 +277,7 @@ /******************************************************************************/ --- a select pipeStage to execute a boolean filter passed as argument. +-- A select pipeStage to execute a boolean filter passed as argument. ::class select public subclass pipeStage ::method init @@ -215,12 +299,19 @@ /******************************************************************************/ -::class CommandNotAllowed -- Security manager +-- A fileTree pipeStage to get the childrens (files or directories) of the current value. +-- The input value can be a string (used as a path) or a .File instance. +-- Use the option 'recursive' to search subdirectories recursively. +::class fileTree public subclass inject -::method unknown - return 0 - -::method command - use strict arg info - raise syntax 98.948 array("Command not allowed:" info~address info~command) +::method init + expose doer + doer = .context~package~findRoutine("fileTreeFind") + self~init:super(doer) +::routine fileTreeFind + use arg value, index + if \value~isA(.File) then value = .File~new(value~string) + childs = value~listFiles + if childs <> .nil then return childs + Modified: sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt =================================================================== --- sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt 2011-06-25 23:51:09 UTC (rev 7012) @@ -104,101 +104,81 @@ 3 : 3 --- Do something for each item (the returned result replaces the value). +-- Do something for each item (the returned result replaces the item's value). .array~of(1, 2, 3)~pipe(.do["return 2*value"] | .displayer) 1 : 2 2 : 4 3 : 6 --- Inject a value for each item. The index of the injected value is made of two indexes. -.array~of(1, 2, 3)~pipe(.inject["value+1"] | .displayer) +-- Inject a value for each item (the returned value is appended). +-- The index of the injected value is pushed on the current index. +.array~of(1, 2, 3)~pipe(.inject["value*10"] pushIndex append | .displayer) 1 : 1 -1.1 : 2 +1|1 : 10 2 : 2 -2.1 : 3 +2|1 : 20 3 : 3 -3.1 : 4 +3|1 : 30 -- Inject two values for each item (each item of the returned collection is written in the pipe). -.array~of(1, 2, 3)~pipe(.inject[".array~of(value+1, value+2)"] | .displayer) +.array~of(1, 2, 3)~pipe(.inject[".array~of(value*10, value*20)"] pushIndex append | .displayer) 1 : 1 -1.1 : 2 -1.2 : 3 +1|1 : 10 +1|2 : 20 2 : 2 -2.1 : 3 -2.2 : 4 +2|1 : 20 +2|2 : 40 3 : 3 -3.1 : 4 -3.2 : 5 +3|1 : 30 +3|2 : 60 -- Each injected value can be used as input to inject a new value, recursively. --- If the recursion is infinite, must specify a limit (here 10). -.array~of(1, 2, 3)~pipe(.inject["value+1"] recursive.10 | .displayer) -1 : 1 -1.1 : 2 -1.1.1 : 3 -1.1.1.1 : 4 -1.1.1.1.1 : 5 -1.1.1.1.1.1 : 6 -1.1.1.1.1.1.1 : 7 -1.1.1.1.1.1.1.1 : 8 -1.1.1.1.1.1.1.1.1 : 9 -1.1.1.1.1.1.1.1.1.1 : 10 -1.1.1.1.1.1.1.1.1.1.1 : 11 -2 : 2 -2.1 : 3 -2.1.1 : 4 -2.1.1.1 : 5 -2.1.1.1.1 : 6 -2.1.1.1.1.1 : 7 -2.1.1.1.1.1.1 : 8 -2.1.1.1.1.1.1.1 : 9 -2.1.1.1.1.1.1.1.1 : 10 -2.1.1.1.1.1.1.1.1.1 : 11 -2.1.1.1.1.1.1.1.1.1.1 : 12 -3 : 3 -3.1 : 4 -3.1.1 : 5 -3.1.1.1 : 6 -3.1.1.1.1 : 7 -3.1.1.1.1.1 : 8 -3.1.1.1.1.1.1 : 9 -3.1.1.1.1.1.1.1 : 10 -3.1.1.1.1.1.1.1.1 : 11 -3.1.1.1.1.1.1.1.1.1 : 12 -3.1.1.1.1.1.1.1.1.1.1 : 13 +-- The default order is depth-first. +-- If the recursion is infinite, must specify a limit (here 0, 1 and 2). +-- The option 'append' is not used, so the initial value is discarded. +.array~of(1, 2, 3)~pipe(.inject["value*10"] pushIndex recursive.0 | .displayer) +1|1 : 10 +2|1 : 20 +3|1 : 30 +.array~of(1, 2, 3)~pipe(.inject["value*20"] pushIndex recursive.1| .displayer) +1|1 : 20 +1|1|1 : 400 +2|1 : 40 +2|1|1 : 800 +3|1 : 60 +3|1|1 : 1200 +.array~of(1, 2, 3)~pipe(.inject["value*30"] pushIndex recursive.2 | .displayer) +1|1 : 30 +1|1|1 : 900 +1|1|1|1 : 27000 +2|1 : 60 +2|1|1 : 1800 +2|1|1|1 : 54000 +3|1 : 90 +3|1|1 : 2700 +3|1|1|1 : 81000 -- Factorial, no value injected for -1 +-- The option 'pushIndex' is not used, so the index remains made of one value. .array~of(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)~pipe(.inject[, "use arg n;", "if n < 0 then return;", "if n == 0 then return 1;", "return n * .context~executable~call(n - 1)"] | .displayer) -1 : -1 -2 : 0 -2.1 : 1 +2 : 1 3 : 1 -3.1 : 1 4 : 2 -4.1 : 2 -5 : 3 -5.1 : 6 -6 : 4 -6.1 : 24 -7 : 5 -7.1 : 120 -8 : 6 -8.1 : 720 -9 : 7 -9.1 : 5040 -10 : 8 -10.1 : 40320 -11 : 9 -11.1 : 362880 +5 : 6 +6 : 24 +7 : 120 +8 : 720 +9 : 5040 +10 : 40320 +11 : 362880 -- Select files whose name contains "rexx" in c:\program files\oorexx @@ -348,162 +328,163 @@ -- Instance methods of the specified classes (not including those inherited). --- Each class is written in the pipeline, followed by the returned methods. +-- Each class is written in the pipeline (option append), followed by the returned methods. +-- The option pushIndex lets have the name of the method in the index. .array~of(.RexxContext, .Package, .Method)~pipe(, - .inject["value~instanceMethods(value~class)"] |, + .inject["value~instanceMethods(value~class)"] append pushIndex |, .sort byIndex |, .displayer, ) 1 : The RexxContext class -1.<> : a Method -1.= : a Method -1.== : a Method -1.>< : a Method -1.BASECLASS : a Method -1.DEFAULTNAME : a Method -1.DEFINE : a Method -1.DELETE : a Method -1.ENHANCED : a Method -1.HASHCODE : a Method -1.ID : a Method -1.INHERIT : a Method -1.ISSUBCLASSOF : a Method -1.METACLASS : a Method -1.METHOD : a Method -1.METHODS : a Method -1.MIXINCLASS : a Method -1.QUERYMIXINCLASS : a Method -1.SUBCLASS : a Method -1.SUBCLASSES : a Method -1.SUPERCLASS : a Method -1.SUPERCLASSES : a Method -1.UNINHERIT : a Method -1.\= : a Method -1.\== : a Method +1|<> : a Method +1|= : a Method +1|== : a Method +1|>< : a Method +1|BASECLASS : a Method +1|DEFAULTNAME : a Method +1|DEFINE : a Method +1|DELETE : a Method +1|ENHANCED : a Method +1|HASHCODE : a Method +1|ID : a Method +1|INHERIT : a Method +1|ISSUBCLASSOF : a Method +1|METACLASS : a Method +1|METHOD : a Method +1|METHODS : a Method +1|MIXINCLASS : a Method +1|QUERYMIXINCLASS : a Method +1|SUBCLASS : a Method +1|SUBCLASSES : a Method +1|SUPERCLASS : a Method +1|SUPERCLASSES : a Method +1|UNINHERIT : a Method +1|\= : a Method +1|\== : a Method 2 : The Package class -2.<> : a Method -2.= : a Method -2.== : a Method -2.>< : a Method -2.BASECLASS : a Method -2.DEFAULTNAME : a Method -2.DEFINE : a Method -2.DELETE : a Method -2.ENHANCED : a Method -2.HASHCODE : a Method -2.ID : a Method -2.INHERIT : a Method -2.ISSUBCLASSOF : a Method -2.METACLASS : a Method -2.METHOD : a Method -2.METHODS : a Method -2.MIXINCLASS : a Method -2.QUERYMIXINCLASS : a Method -2.SUBCLASS : a Method -2.SUBCLASSES : a Method -2.SUPERCLASS : a Method -2.SUPERCLASSES : a Method -2.UNINHERIT : a Method -2.\= : a Method -2.\== : a Method +2|<> : a Method +2|= : a Method +2|== : a Method +2|>< : a Method +2|BASECLASS : a Method +2|DEFAULTNAME : a Method +2|DEFINE : a Method +2|DELETE : a Method +2|ENHANCED : a Method +2|HASHCODE : a Method +2|ID : a Method +2|INHERIT : a Method +2|ISSUBCLASSOF : a Method +2|METACLASS : a Method +2|METHOD : a Method +2|METHODS : a Method +2|MIXINCLASS : a Method +2|QUERYMIXINCLASS : a Method +2|SUBCLASS : a Method +2|SUBCLASSES : a Method +2|SUPERCLASS : a Method +2|SUPERCLASSES : a Method +2|UNINHERIT : a Method +2|\= : a Method +2|\== : a Method 3 : The Method class -3.!DEFINE_CLASS_METHOD : a Method -3.!DEFINE_METHODS : a Method -3.!REXXDEFINED : a Method -3.<> : a Method -3.= : a Method -3.== : a Method -3.>< : a Method -3.BASECLASS : a Method -3.DEFAULTNAME : a Method -3.DEFINE : a Method -3.DELETE : a Method -3.ENHANCED : a Method -3.HASHCODE : a Method -3.ID : a Method -3.INHERIT : a Method -3.ISSUBCLASSOF : a Method -3.METACLASS : a Method -3.METHOD : a Method -3.METHODS : a Method -3.MIXINCLASS : a Method -3.QUERYMIXINCLASS : a Method -3.SUBCLASS : a Method -3.SUBCLASSES : a Method -3.SUPERCLASS : a Method -3.SUPERCLASSES : a Method -3.UNINHERIT : a Method -3.\= : a Method -3.\== : a Method +3|!DEFINE_CLASS_METHOD : a Method +3|!DEFINE_METHODS : a Method +3|!REXXDEFINED : a Method +3|<> : a Method +3|= : a Method +3|== : a Method +3|>< : a Method +3|BASECLASS : a Method +3|DEFAULTNAME : a Method +3|DEFINE : a Method +3|DELETE : a Method +3|ENHANCED : a Method +3|HASHCODE : a Method +3|ID : a Method +3|INHERIT : a Method +3|ISSUBCLASSOF : a Method +3|METACLASS : a Method +3|METHOD : a Method +3|METHODS : a Method +3|MIXINCLASS : a Method +3|QUERYMIXINCLASS : a Method +3|SUBCLASS : a Method +3|SUBCLASSES : a Method +3|SUPERCLASS : a Method +3|SUPERCLASSES : a Method +3|UNINHERIT : a Method +3|\= : a Method +3|\== : a Method -- Methods (not inherited) of all the classes whose id starts with "R". .environment~pipe(, .select["value~isA(.class)"] |, .select["value~id~caselessAbbrev('R') <> 0"] |, - .inject["value~methods(value)"] |, + .inject["value~methods(value)"] append pushIndex |, .sort byIndex |, .displayer, ) RELATION : The Relation class -RELATION.ALLAT : a Method -RELATION.ALLINDEX : a Method -RELATION.ALLINDEXES : a Method -RELATION.ALLITEMS : a Method -RELATION.AT : a Method -RELATION.DIFFERENCE : a Method -RELATION.EMPTY : a Method -RELATION.HASINDEX : a Method -RELATION.HASITEM : a Method -RELATION.INDEX : a Method -RELATION.INTERSECTION : a Method -RELATION.ISEMPTY : a Method -RELATION.ITEMS : a Method -RELATION.MAKEARRAY : a Method -RELATION.PUT : a Method -RELATION.READOBJECT : a Method -RELATION.REMOVE : a Method -RELATION.REMOVEALL : a Method -RELATION.REMOVEITEM : a Method -RELATION.SUBSET : a Method -RELATION.SUPPLIER : a Method -RELATION.UNION : a Method -RELATION.WRITEOBJECT : a Method -RELATION.XOR : a Method -RELATION.[] : a Method -RELATION.[]= : a Method +RELATION|ALLAT : a Method +RELATION|ALLINDEX : a Method +RELATION|ALLINDEXES : a Method +RELATION|ALLITEMS : a Method +RELATION|AT : a Method +RELATION|DIFFERENCE : a Method +RELATION|EMPTY : a Method +RELATION|HASINDEX : a Method +RELATION|HASITEM : a Method +RELATION|INDEX : a Method +RELATION|INTERSECTION : a Method +RELATION|ISEMPTY : a Method +RELATION|ITEMS : a Method +RELATION|MAKEARRAY : a Method +RELATION|PUT : a Method +RELATION|READOBJECT : a Method +RELATION|REMOVE : a Method +RELATION|REMOVEALL : a Method +RELATION|REMOVEITEM : a Method +RELATION|SUBSET : a Method +RELATION|SUPPLIER : a Method +RELATION|UNION : a Method +RELATION|WRITEOBJECT : a Method +RELATION|XOR : a Method +RELATION|[] : a Method +RELATION|[]= : a Method REXXCONTEXT : The RexxContext class -REXXCONTEXT.ARGS : a Method -REXXCONTEXT.CONDITION : a Method -REXXCONTEXT.COPY : a Method -REXXCONTEXT.DIGITS : a Method -REXXCONTEXT.EXECUTABLE : a Method -REXXCONTEXT.FORM : a Method -REXXCONTEXT.FUZZ : a Method -REXXCONTEXT.LINE : a Method -REXXCONTEXT.PACKAGE : a Method -REXXCONTEXT.RS : a Method -REXXCONTEXT.VARIABLES : a Method +REXXCONTEXT|ARGS : a Method +REXXCONTEXT|CONDITION : a Method +REXXCONTEXT|COPY : a Method +REXXCONTEXT|DIGITS : a Method +REXXCONTEXT|EXECUTABLE : a Method +REXXCONTEXT|FORM : a Method +REXXCONTEXT|FUZZ : a Method +REXXCONTEXT|LINE : a Method +REXXCONTEXT|PACKAGE : a Method +REXXCONTEXT|RS : a Method +REXXCONTEXT|VARIABLES : a Method REXXQUEUE : The RexxQueue class -REXXQUEUE.DELETE : a Method -REXXQUEUE.EMPTY : a Method -REXXQUEUE.GET : a Method -REXXQUEUE.INIT : a Method -REXXQUEUE.LINEIN : a Method -REXXQUEUE.LINEOUT : a Method -REXXQUEUE.MAKEARRAY : a Method -REXXQUEUE.PULL : a Method -REXXQUEUE.PUSH : a Method -REXXQUEUE.QUEUE : a Method -REXXQUEUE.QUEUED : a Method -REXXQUEUE.SAY : a Method -REXXQUEUE.SET : a Method +REXXQUEUE|DELETE : a Method +REXXQUEUE|EMPTY : a Method +REXXQUEUE|GET : a Method +REXXQUEUE|INIT : a Method +REXXQUEUE|LINEIN : a Method +REXXQUEUE|LINEOUT : a Method +REXXQUEUE|MAKEARRAY : a Method +REXXQUEUE|PULL : a Method +REXXQUEUE|PUSH : a Method +REXXQUEUE|QUEUE : a Method +REXXQUEUE|QUEUED : a Method +REXXQUEUE|SAY : a Method +REXXQUEUE|SET : a Method ROUTINE : The Routine class -ROUTINE.CALL : a Method -ROUTINE.CALLWITH : a Method -ROUTINE.PACKAGE : a Method -ROUTINE.SETSECURITYMANAGER : a Method -ROUTINE.SOURCE : a Method +ROUTINE|CALL : a Method +ROUTINE|CALLWITH : a Method +ROUTINE|PACKAGE : a Method +ROUTINE|SETSECURITYMANAGER : a Method +ROUTINE|SOURCE : a Method -- All packages that are visible from current context, including the current package (source of the pipeline). @@ -511,37 +492,108 @@ -- extensions.cls --> doers.cls --> extensions.cls -- This is because of Doers.AddVisibilityFrom. .context~package~pipe(, - .inject["value~importedPackages"] recursive |, - .displayer index.10, + .inject["value~importedPackages"] recursive append pushIndex |, + .displayer index.15, "' '~copies(index~items)", ".file~new(value~name)~name", newline, ) -1 pipe_extension_test.rex -1.1 extensions.cls -1.1.1 doers.cls -1.1.1.1 extensions.cls -1.1.2 functionals.cls -1.1.2.1 doers.cls -1.1.2.1.1 extensions.cls -1.2 coactivity.cls -1.2.1 activity.cls -1.3 pipe_extension.cls -1.3.1 pipe.rex -1.3.2 doers.cls -1.3.2.1 extensions.cls -1.3.2.1.1 doers.cls -1.3.2.2 coactivity.cls -1.3.2.2.1 activity.cls -1.3.2.3 pipe_extension.cls -1.3.3 coactivity.cls -1.3.3.1 activity.cls -1.3.4 rgf_util2_wrappers.rex -1.3.4.1 rgf_util2.rex -1.4 rgf_util2_wrappers.rex -1.4.1 rgf_util2.rex +1 pipe_extension_test.rex +1|1 extensions.cls +1|1|1 doers.cls +1|1|1|2 coactivity.cls +1|1|1|2|1 activity.cls +1|1|1|3 pipe_extension.cls +1|1|1|3|1 pipe.rex +1|1|1|3|3 coactivity.cls +1|1|1|3|3|1 activity.cls +1|1|1|3|4 rgf_util2_wrappers.rex +1|1|1|3|4|1 rgf_util2.rex +1|1|1|4 rgf_util2_wrappers.rex +1|1|1|4|1 rgf_util2.rex +1|1|2 functionals.cls +1|1|2|1 doers.cls +1|1|2|1|2 coactivity.cls +1|1|2|1|2|1 activity.cls +1|1|2|1|3 pipe_extension.cls +1|1|2|1|3|1 pipe.rex +1|1|2|1|3|3 coactivity.cls +1|1|2|1|3|3|1 activity.cls +1|1|2|1|3|4 rgf_util2_wrappers.rex +1|1|2|1|3|4|1 rgf_util2.rex +1|1|2|1|4 rgf_util2_wrappers.rex +1|1|2|1|4|1 rgf_util2.rex +1|2 coactivity.cls +1|2|1 activity.cls +1|3 pipe_extension.cls +1|3|1 pipe.rex +1|3|2 doers.cls +1|3|2|1 extensions.cls +1|3|2|1|2 functionals.cls +1|3|2|2 coactivity.cls +1|3|2|2|1 activity.cls +1|3|2|4 rgf_util2_wrappers.rex +1|3|2|4|1 rgf_util2.rex +1|3|3 coactivity.cls +1|3|3|1 activity.cls +1|3|4 rgf_util2_wrappers.rex +1|3|4|1 rgf_util2.rex +1|4 rgf_util2_wrappers.rex +1|4|1 rgf_util2.rex +-- Same as above, but in breadth-first order +.context~package~pipe(, + .inject["value~importedPackages"] recursive.breadthFirst append pushIndex |, + .displayer index.15, + "' '~copies(index~items)", + ".file~new(value~name)~name", + newline, + ) +1 pipe_extension_test.rex +1|1 extensions.cls +1|2 coactivity.cls +1|3 pipe_extension.cls +1|4 rgf_util2_wrappers.rex +1|1|1 doers.cls +1|1|2 functionals.cls +1|2|1 activity.cls +1|3|1 pipe.rex +1|3|2 doers.cls +1|3|3 coactivity.cls +1|3|4 rgf_util2_wrappers.rex +1|4|1 rgf_util2.rex +1|1|1|2 coactivity.cls +1|1|1|3 pipe_extension.cls +1|1|1|4 rgf_util2_wrappers.rex +1|1|2|1 doers.cls +1|3|2|1 extensions.cls +1|3|2|2 coactivity.cls +1|3|2|4 rgf_util2_wrappers.rex +1|3|3|1 activity.cls +1|3|4|1 rgf_util2.rex +1|1|1|2|1 activity.cls +1|1|1|3|1 pipe.rex +1|1|1|3|3 coactivity.cls +1|1|1|3|4 rgf_util2_wrappers.rex +1|1|1|4|1 rgf_util2.rex +1|1|2|1|2 coactivity.cls +1|1|2|1|3 pipe_extension.cls +1|1|2|1|4 rgf_util2_wrappers.rex +1|3|2|1|2 functionals.cls +1|3|2|2|1 activity.cls +1|3|2|4|1 rgf_util2.rex +1|1|1|3|3|1 activity.cls +1|1|1|3|4|1 rgf_util2.rex +1|1|2|1|2|1 activity.cls +1|1|2|1|3|1 pipe.rex +1|1|2|1|3|3 coactivity.cls +1|1|2|1|3|4 rgf_util2_wrappers.rex +1|1|2|1|4|1 rgf_util2.rex +1|1|2|1|3|3|1 activity.cls +1|1|2|1|3|4|1 rgf_util2.rex + + -- The .take pipeStage lets stop the preceding pipeStages when the number of items to take -- has been reached, whatever its position in the pipeline. supplier = .array~of(1,2,3,4,5,6,7,8,9)~supplier @@ -608,7 +660,68 @@ -- Remove header and footer -.array~of("header", 1, 2 ,3 , "footer")~pipe(.drop first 1 | .drop last 1 | .displayer) +.array~of("header", 1, 2 ,3 , "footer")~pipe(.drop first | .drop last | .displayer) 2 : 1 3 : 2 4 : 3 + + +-- The *.txt files of ooRexx +"c:\program files\oorexx"~pipe(, + .fileTree recursive |, + .select["filespec('e', value~name) == 'txt'"] |, + .displayer, + ) +1 : c:\program files\oorexx\CPLv1.0.txt +1 : c:\program files\oorexx\doc\CHANGES.txt +1 : c:\program files\oorexx\doc\ReleaseNotes.txt +1 : c:\program files\oorexx\samples\api\readme.txt +1 : c:\program files\oorexx\samples\api\wpipe\readme.txt +1 : c:\program files\oorexx\samples\ole\oleinfo\help.txt +1 : c:\program files\oorexx\samples\oodialog\examples\readme.txt +1 : c:\program files\oorexx\samples\oodialog\wav\readme.txt + + +-- Alphanumeric words found in the *.txt files of ooRexx. +-- +-- Exemple of result : +-- 1|c:\program files\oorexx\CPLv1.0.txt|149|8 : appropriateness +-- "appropriateness" is the 8th word of the 149th line of the file +-- "c:\program files\oorexx\CPLv1.0.txt" +-- +-- To investigate : I get sometimes a crash in the sort. +-- +"c:\program files\oorexx"~pipe(, + .fileTree recursive |, + .select["filespec('e', value~name) == 'txt'"] |, + .fileText | .words | .select["value~datatype('a') & value~length >= 15"] |, + .sort caseless | .displayer, + ) +1|c:\program files\oorexx\CPLv1.0.txt|149|8 : appropriateness +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|56|10 : GetKnownMethods +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|60|1 : GetKnownMethods +1|c:\program files\oorexx\doc\ReleaseNotes.txt|146|1 : isCaseSensitive +1|c:\program files\oorexx\doc\ReleaseNotes.txt|162|1 : isCaseSensitive +1|c:\program files\oorexx\CPLv1.0.txt|84|8 : merchantability +1|c:\program files\oorexx\CPLv1.0.txt|148|2 : MERCHANTABILITY +1|c:\program files\oorexx\samples\api\readme.txt|27|8 : MERCHANTABILITY +1|c:\program files\oorexx\samples\api\wpipe\readme.txt|27|8 : MERCHANTABILITY +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|27|8 : MERCHANTABILITY +1|c:\program files\oorexx\samples\oodialog\examples\readme.txt|26|8 : MERCHANTABILITY +1|c:\program files\oorexx\samples\oodialog\wav\readme.txt|27|8 : MERCHANTABILITY +1|c:\program files\oorexx\samples\api\readme.txt|15|2 : Redistributions +1|c:\program files\oorexx\samples\api\readme.txt|17|2 : Redistributions +1|c:\program files\oorexx\samples\api\wpipe\readme.txt|15|2 : Redistributions +1|c:\program files\oorexx\samples\api\wpipe\readme.txt|17|2 : Redistributions +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|15|2 : Redistributions +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|17|2 : Redistributions +1|c:\program files\oorexx\samples\oodialog\examples\readme.txt|14|2 : Redistributions +1|c:\program files\oorexx\samples\oodialog\examples\readme.txt|16|2 : Redistributions +1|c:\program files\oorexx\samples\oodialog\wav\readme.txt|15|2 : Redistributions +1|c:\program files\oorexx\samples\oodialog\wav\readme.txt|17|2 : Redistributions +1|c:\program files\oorexx\CPLv1.0.txt|113|8 : responsibilities +1|c:\program files\oorexx\doc\CHANGES.txt|79|3 : RexxRegisterFunctionDLL +1|c:\program files\oorexx\doc\ReleaseNotes.txt|234|1 : SysGetservbyname +1|c:\program files\oorexx\doc\ReleaseNotes.txt|235|1 : SysGetservbyport +1|c:\program files\oorexx\doc\ReleaseNotes.txt|237|1 : SysGetsizeofptr +1|c:\program files\oorexx\samples\ole\oleinfo\help.txt|98|5 : VersionIndependentProgID Modified: sandbox/jlf/samples/pipeline/pipe_extension_test.rex =================================================================== --- sandbox/jlf/samples/pipeline/pipe_extension_test.rex 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/samples/pipeline/pipe_extension_test.rex 2011-06-25 23:51:09 UTC (rev 7012) @@ -61,24 +61,30 @@ .array~of(1, 2, 3)~pipe(.do["say 'value='value 'index='index"] | .displayer) --- Do something for each item (the returned result replaces the value). +-- Do something for each item (the returned result replaces the item's value). .array~of(1, 2, 3)~pipe(.do["return 2*value"] | .displayer) --- Inject a value for each item. The index of the injected value is made of two indexes. -.array~of(1, 2, 3)~pipe(.inject["value+1"] | .displayer) +-- Inject a value for each item (the returned value is appended). +-- The index of the injected value is pushed on the current index. +.array~of(1, 2, 3)~pipe(.inject["value*10"] pushIndex append | .displayer) -- Inject two values for each item (each item of the returned collection is written in the pipe). -.array~of(1, 2, 3)~pipe(.inject[".array~of(value+1, value+2)"] | .displayer) +.array~of(1, 2, 3)~pipe(.inject[".array~of(value*10, value*20)"] pushIndex append | .displayer) -- Each injected value can be used as input to inject a new value, recursively. --- If the recursion is infinite, must specify a limit (here 10). -.array~of(1, 2, 3)~pipe(.inject["value+1"] recursive.10 | .displayer) +-- The default order is depth-first. +-- If the recursion is infinite, must specify a limit (here 0, 1 and 2). +-- The option 'append' is not used, so the initial value is discarded. +.array~of(1, 2, 3)~pipe(.inject["value*10"] pushIndex recursive.0 | .displayer) +.array~of(1, 2, 3)~pipe(.inject["value*20"] pushIndex recursive.1| .displayer) +.array~of(1, 2, 3)~pipe(.inject["value*30"] pushIndex recursive.2 | .displayer) -- Factorial, no value injected for -1 +-- The option 'pushIndex' is not used, so the index remains made of one value. .array~of(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)~pipe(.inject[, "use arg n;", "if n < 0 then return;", @@ -132,9 +138,10 @@ -- Instance methods of the specified classes (not including those inherited). --- Each class is written in the pipeline, followed by the returned methods. +-- Each class is written in the pipeline (option append), followed by the returned methods. +-- The option pushIndex lets have the name of the method in the index. .array~of(.RexxContext, .Package, .Method)~pipe(, - .inject["value~instanceMethods(value~class)"] |, + .inject["value~instanceMethods(value~class)"] append pushIndex |, .sort byIndex |, .displayer, ) @@ -144,7 +151,7 @@ .environment~pipe(, .select["value~isA(.class)"] |, .select["value~id~caselessAbbrev('R') <> 0"] |, - .inject["value~methods(value)"] |, + .inject["value~methods(value)"] append pushIndex |, .sort byIndex |, .displayer, ) @@ -155,14 +162,24 @@ -- extensions.cls --> doers.cls --> extensions.cls -- This is because of Doers.AddVisibilityFrom. .context~package~pipe(, - .inject["value~importedPackages"] recursive |, - .displayer index.10, + .inject["value~importedPackages"] recursive append pushIndex |, + .displayer index.15, "' '~copies(index~items)", ".file~new(value~name)~name", newline, ) +-- Same as above, but in breadth-first order +.context~package~pipe(, + .inject["value~importedPackages"] recursive.breadthFirst append pushIndex |, + .displayer index.15, + "' '~copies(index~items)", + ".file~new(value~name)~name", + newline, + ) + + -- The .take pipeStage lets stop the preceding pipeStages when the number of items to take -- has been reached, whatever its position in the pipeline. supplier = .array~of(1,2,3,4,5,6,7,8,9)~supplier @@ -195,9 +212,34 @@ -- Remove header and footer -.array~of("header", 1, 2 ,3 , "footer")~pipe(.drop first 1 | .drop last 1 | .displayer) +.array~of("header", 1, 2 ,3 , "footer")~pipe(.drop first | .drop last | .displayer) +-- The *.txt files of ooRexx +"c:\program files\oorexx"~pipe(, + .fileTree recursive |, + .select["filespec('e', value~name) == 'txt'"] |, + .displayer, + ) + + +-- Alphanumeric words found in the *.txt files of ooRexx. +-- +-- Exemple of result : +-- 1|c:\program files\oorexx\CPLv1.0.txt|149|8 : appropriateness +-- "appropriateness" is the 8th word of the 149th line of the file +-- "c:\program files\oorexx\CPLv1.0.txt" +-- +-- To investigate : I get sometimes a crash in the sort. +-- +"c:\program files\oorexx"~pipe(, + .fileTree recursive |, + .select["filespec('e', value~name) == 'txt'"] |, + .fileText | .words | .select["value~datatype('a') & value~length >= 15"] |, + .sort caseless | .displayer, + ) + + ------------------------------------------------------------------------------- ::routine evaluate use strict arg routineName Modified: sandbox/jlf/samples/pipeline/pipe_readme.txt =================================================================== --- sandbox/jlf/samples/pipeline/pipe_readme.txt 2011-06-23 04:12:43 UTC (rev 7011) +++ sandbox/jlf/samples/pipeline/pipe_readme.txt 2011-06-25 23:51:09 UTC (rev 7012) @@ -19,6 +19,10 @@ merge : send a 'done' message displayer : process does forward class (super) --> why needed here, and not in other classes ? +answer : because .displayer does not transform the values, it just displays them. So it can +forward to class (super) which will take care of sending the value & index to next pipestage. +The other classes transform the values, and write themselves the new value. If they forwarded +to class (super) then the unchanged value would be also sent to the next pipeStage. http://freshmeat.net/projects/pv This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |