From: <jfa...@us...> - 2011-07-24 22:13:44
|
Revision: 7078 http://oorexx.svn.sourceforge.net/oorexx/?rev=7078&view=rev Author: jfaucher Date: 2011-07-24 22:13:36 +0000 (Sun, 24 Jul 2011) Log Message: ----------- Refactoring of doers. More work on pipes. Modified Paths: -------------- sandbox/jlf/_diary.txt sandbox/jlf/samples/concurrency/coactivity.cls sandbox/jlf/samples/extension/doers.cls sandbox/jlf/samples/extension/functional-test.rex sandbox/jlf/samples/pipeline/deadlock1.rex 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 sandbox/jlf/samples/pipeline/pipe_test.rex sandbox/jlf/samples/profiling/profiling.cls Modified: sandbox/jlf/_diary.txt =================================================================== --- sandbox/jlf/_diary.txt 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/_diary.txt 2011-07-24 22:13:36 UTC (rev 7078) @@ -43,6 +43,33 @@ =============================================================================== +2011 july 25 + +[pipe] +.displayer renamed .console, to be closer to CMS pipeline. + + +[pipe extensions] +Refactoring of makeFunctionDoer and makeActionDoer : now implemented in doers.cls +as methods functionDoer and actionDoer on RexxContextualSource. + + +[doers] +New class ClauseSupplier which lets iterate over the clauses of a source and replace +a clause by a new clause. + +New method sourceDoer which lets transform the source before creating a doer from it. +This method is used by functionDoer and actionDoer . +Ex : + {if value==0 then "infinity" ; else 1/value}~functionDoer("use arg value") +returns a routine built using this transformed source + {use arg value -- optional source fragment passed as parameter to functionDoer + option "NOCOMMANDS" -- added by functionDoer : expressions are not commands in functions + if value==0 then "infinity" else 1/value -- original source literal, unchanged + if var("result") then return result} -- added by functionDoer : returns the result of the last evaluated expression + + +=============================================================================== 2011 july 21 [expression evaluation] Modified: sandbox/jlf/samples/concurrency/coactivity.cls =================================================================== --- sandbox/jlf/samples/concurrency/coactivity.cls 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/concurrency/coactivity.cls 2011-07-24 22:13:36 UTC (rev 7078) @@ -300,7 +300,7 @@ ::method uninit /* I think I need the uninit method to support properly this use case : - .coactivity~new("i=0; do forever; i+=1; .yield[i]; end")~pipe(.take 5 | .displayer) + .coactivity~new{i=0; do forever; i+=1; .yield[i]; end}~pipe(.take 5 | .displayer) While the pipeline is running, the coactivity supplier is referenced by the 'source' property of the first pipe stage, and can't be GC'ed. The pipeline itself can't be GC'ed because the first pipe stage is referenced from the call stack, as an argument of 'pipe'. When 5 values have been taken (.take 5), the pipeline is stopped and the method 'pipe' returns. Modified: sandbox/jlf/samples/extension/doers.cls =================================================================== --- sandbox/jlf/samples/extension/doers.cls 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/extension/doers.cls 2011-07-24 22:13:36 UTC (rev 7078) @@ -5,11 +5,123 @@ --::options trace i ----------------------------------------------------------------------------- --- Mixins. +-- Mixin. +/* +A DoerFactory is an object who knows how to create a doer. +A doer can be created from : +- a source (String or RexxContextualSource) : + Can be costly since the interpreter must parse the source and create an AST. + But you do it only once... After, you get an executable in your hands, which you can use + as a target for the 'do' message. +- an executable (Routine or Method) : + No cost, this is for convenience, the doer is the executable itself. + +Examples : + +doer = {use arg name; say "hello" name}~doer +say doer~class -- The Routine class +doer~do("John") -- hello John +say + +doer = {::method say "hello" self}~doer +say doer~class -- The Method class +doer~do("John") -- hello John +say + +-- By default, a string is a message +doer = "length"~doer +say doer~class -- The String class +say doer~do("John") -- 4 +say + +-- If you want to use a string as source holder, then you must call sourceDoer +doer = 'use arg name; say "hello" name'~sourceDoer +say doer~class -- The Routine class +doer~do("John") -- hello John +say + +doer = '::method say "hello" self'~sourceDoer +say doer~class -- The Method class +doer~do("John") -- hello John +say + +-- Implicit arguments and implicit return. +-- The original source +-- x~length +-- becomes : +-- use arg x ; options NOCOMMANDS ; x~length +-- return result +doer = {x~length}~sourceDoer("use arg x ; options NOCOMMANDS", "return result") +say doer~class -- The Routine class +say doer~do("John") -- 4 +say + +-- The method functionDoer takes care of the implicit return +doer = {x~length}~functionDoer("use arg x") +say doer~class -- The Routine class +say doer~do("John") -- 4 + +*/ + +::class DoerFactory mixinclass Object public + +::method doer abstract + +::method sourceDoer -- Helper to create a doer from a source, after transformation of the source if needed/requested + use strict arg before="", after="", context=.nil + if context == .nil then context = self~package -- lookup scope + + sourceArray = self~source -- always an array, even if empty or just one line + if sourceArray~items == 0 then raise syntax 93.900 array("No source available") + clauseSupplier = .ClauseSupplier~new(sourceArray) -- yes, the supplier works directly on the source array (no copy) + + -- If the first word of the source is ::method then remove this word and remember it's a method. + -- If the first word of the source is ::routine then remove this word and remember it's a routine. + isRoutine = \ self~isA(.method) -- routine by default, unless self is a method + if clauseSupplier~available then do + clause = clauseSupplier~item + parse var clause word rest + if word~caselessEquals("::method") then do ; clauseSupplier~item = rest ; isRoutine = .false ; end + if word~caselessEquals("::routine") then do ; clauseSupplier~item = rest ; isRoutine = .true ; end + end + + -- Insert the 'before' source fragment, if any + if before <> "" then do + -- If the next word is "expose" then must ensure that this clause remains the first clause. + if clauseSupplier~available then do + clause = clauseSupplier~item + parse var clause word rest + if word~caselessEquals("expose") then clauseSupplier~item = clause ";" before + else clauseSupplier~item = before ";" clause + end + else sourceArray~append(before) + end + + -- Insert the 'after' source fragment, if any + if after <> "" then sourceArray~append(after) + + -- Returns the executable + if isRoutine then return .Routine~new("", sourceArray, context) + else return .Method~new("", sourceArray, context) + + +----------------------------------------------------------------------------- +-- Mixin. -- A Doer is an object who knows how to execute itself (understands "do") +-- This is an abstraction of routine, method and message. -::class RoutineDoer mixinclass Object public +::class Doer mixinclass Object public inherit DoerFactory +::method needsObject abstract +::method do abstract +::method doWith abstract + + +----------------------------------------------------------------------------- +-- Mixin. + +::class RoutineDoer mixinclass Object public inherit Doer + ::method doer use strict arg -- none return self @@ -27,13 +139,16 @@ if var("result") then return result +----------------------------------------------------------------------------- +-- Mixin. + /* To investigate : The method 'run' is a private method. So can be called only from another method of object... -"hello"~run("::method say self"~doer) --> Error : Object "hello" does not understand message "RUN" (ok, 'run' is private) -"::method say self"~doer~do("hello") --> No error, display "hello" (so the private method is visible ?) +"hello"~run({::method say self}~doer) --> Error : Object "hello" does not understand message "RUN" (ok, 'run' is private) +{::method say self}~doer~do("hello") --> No error, display "hello" (so the private method is visible ?) */ -::class MethodDoer mixinclass Object public +::class MethodDoer mixinclass Object public inherit Doer ::method doer use strict arg -- none @@ -53,11 +168,14 @@ if var("result") then return result -::class StringDoer mixinclass Object public +----------------------------------------------------------------------------- +-- Mixin. +::class StringDoer mixinclass Object public inherit Doer + ::method doer use strict arg -- none - return self -- When used as a doer, a string is a message + return self -- When used as a doer factory, a string is a message ::method needsObject return .true -- Must pass an object as first argument when calling do or doWith @@ -72,15 +190,100 @@ object~sendWith(self, array) if var("result") then return result +-- Using a string as source holder is no longer necessary, +-- because RexxContextualSource is now available. +-- But I keep the possibility, just in case... +::method source + return .array~of(self) -::class RexxContextualSourceDoer mixinclass Object public +-- Needed if you want to run sourceDoer on a string. +-- Most of the time, the package returned by this method will not answer to your +-- needs, because a routine/method created with this package as context will have +-- a lookup scope limited to the doers package. Of course, you can pass explicitely +-- another package to sourceDoer (typically the caller's package), but that's tedious +-- to do that each time. +-- Thats's why RexxContextualSource has been added, it holds a reference to the package +-- that defined it. +::method package + return .context~package + +----------------------------------------------------------------------------- +-- Mixin. + +::class RexxContextualSourceDoer mixinclass Object public inherit Doer + ::method doer use strict arg -- none - parse value self~source with word1 rest + return self~sourceDoer + +-- Could be defined on DoerFactory to give access to this functionality from any doer, +-- but that's probably a bad idea. Other doers are directly executable (except String +-- when using sourceDoer - but that's deprecated) and I consider that the "shortest source" +-- criteria doesn't apply to them. So they will have already the right arguments and an +-- explicit return, if needed. +::method functionDoer + use strict arg before="", after="" + before ||= ' ; options "NOCOMMANDS"' + after ||= ' ; if var("result") then return result' + return self~sourceDoer(before, after) + +-- Same remark as above. +::method actionDoer + use strict arg before="", after="" + return self~sourceDoer(before, after) + + +----------------------------------------------------------------------------- +-- Helper for source analysis & transformation. + +::class ClauseSupplier + +::method init + expose sourceArray lineNum clauseStart clauseEnd + use strict arg sourceArray + lineNum = sourceArray~first + clauseStart = 1 + clauseEnd = -1 -- indicator of first call to next + self~next + +::method available + expose lineNum + return lineNum <> .nil + +::method index + expose lineNum clauseStart + if \ self~available then raise syntax 937 + return lineNum clauseStart + +::method item + expose clause + if \ self~available then raise syntax 937 + return clause + +::method "item=" -- replace the current clause by the new source fragment (black box, can be several clauses, won't be scanned) + expose sourceArray lineNum clauseStart clauseEnd clause + if \ self~available then raise syntax 937 + use strict arg newSourceFragment + oldLength = clause~length + newLength = newSourceFragment~length + sourceLine = sourceArray[lineNum] + sourceArray[lineNum] = sourceLine~replaceAt(newSourceFragment, clauseStart, oldLength) + if clauseEnd > 0 then clauseEnd += newLength - oldLength -- yes, continue AFTER the new source fragment - if word1~caselessEquals("::method") then return .Method~new("", rest, self~package) - if word1~caselessEquals("::routine") then return .Routine~new("", rest, self~package) - -- Routine by default - return .Routine~new("", self~source, self~package) +::method next -- non empty clause + expose sourceArray lineNum clauseStart clauseEnd clause + do while lineNum <> .nil + if clauseEnd == 0 then do + clauseStart = 1 + lineNum = sourceArray~next(lineNum) + end + else if clauseEnd > 0 then clauseStart = clauseEnd + 1 + sourceLine = sourceArray[lineNum] + clauseEnd = sourceLine~pos(";", clauseStart) + if clauseEnd == 0 then clauseLength = sourceLine~length - clauseStart + 1 + else clauseLength = clauseEnd - clauseStart + clause = sourceLine~substr(clauseStart, clauseLength) + if clause~strip <> "" then return + end Modified: sandbox/jlf/samples/extension/functional-test.rex =================================================================== --- sandbox/jlf/samples/extension/functional-test.rex 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/extension/functional-test.rex 2011-07-24 22:13:36 UTC (rev 7078) @@ -68,8 +68,8 @@ .CircularQueue~of(1,2,3,4)~map{return arg(1) * 2}~dump -- 2,4,6,8 : 2, 4, 6, 8 (strange : the class is not displayed) .CircularQueue~of(1,2,3,4)~map{use arg n ; if n == 0 then return 1 ; return n * .context~executable~call(n - 1)}~dump -- 1,2,6,24 : 1, 2, 6, 24 -"abcdefghijklmnopqrstuvwxyz"~mapchar{return arg(1)~verify('aeiouy')}~dump -.MutableBuffer~new("abcdefghijklmnopqrstuvwxyz")~mapchar{if arg(1)~verify('aeiouy') == 1 then return arg(1) ; else return ''}~dump +"abcdefghijklmnopqrstuvwxyz"~mapchar{return arg(1)~verify('aeiouy')}~dump -- 01110111011111011111011101 +.MutableBuffer~new("abcdefghijklmnopqrstuvwxyz")~mapchar{if arg(1)~verify('aeiouy') == 1 then return arg(1) ; else return ''}~dump -- bcdfghjklmnpqrstvwxz /* todo : doesn't work because the variable translation has no value when evaluating the doer translation = .Directory~of("quick", "slow", "lazy", "nervous", "brown", "yellow", "dog", "cat") @@ -101,10 +101,17 @@ colors~map{::method return self~rgbInteger "("self~redIntensity", "self~greenIntensity", "self~blueIntensity")"}~dump -- an Array : 0 (0, 0, 0), 255 (0, 0, 255), 32768 (0, 128, 0), 12500670 (190, 190, 190) -- A method object can be used directly --- No need to define the method on the receiver class +-- No need to define the method on the receiver class... colors~map(.methods~entry("decimalColor"))~dump -- an Array : 0 (0, 0, 0), 255 (0, 0, 255), 32768 (0, 128, 0), 12500670 (190, 190, 190) +-- ... except when the method is recursive and recalls itself by name +.String~define("factorial", .methods~entry("factorial")) +.Array~of(1,2,3,4)~map(.methods~entry("factorial"))~dump -- an Array : 1, 2, 6, 24 +-- Here, the method is recursive, but does not recall itself by name +.Array~of(1,2,3,4)~map(.methods~entry("factorialExecutable"))~dump -- an Array : 1, 2, 6, 24 + + ----------------------------------------------------------------- -- Definitions ----------------------------------------------------------------- @@ -112,14 +119,19 @@ ::routine factorial use strict arg n if n == 0 then return 1 - return n * factorial(n - 1) + return n * factorial(n - 1) -- here, the routine 'factorial' has a global name, and can be called ::method factorial if self == 0 then return 1 - return self * (self - 1)~factorial + return self * (self - 1)~factorial -- this code will work only if self understands 'factorial' +::method factorialExecutable + if self == 0 then return 1 + return self * (self - 1)~run(.context~executable) -- recursive call, but not by name + + ::method decimalColor return self~rgbInteger "("self~redIntensity", "self~greenIntensity", "self~blueIntensity")" Modified: sandbox/jlf/samples/pipeline/deadlock1.rex =================================================================== --- sandbox/jlf/samples/pipeline/deadlock1.rex 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/pipeline/deadlock1.rex 2011-07-24 22:13:36 UTC (rev 7078) @@ -26,7 +26,7 @@ --call Doers.AddVisibilityFrom(.context) -.coactivity~new({.coactivity~yield("a") ; .coactivity~yield("b")})~pipe(.upper|.displayer) +.coactivity~new({.coactivity~yield("a") ; .coactivity~yield("b")})~pipe(.upper|.console) --::options trace i ::requires "extension/extensions.cls" @@ -53,7 +53,7 @@ T1 A4 24 *-* call Doers.AddVisibilityFrom(.context) T1 A4 >E> .CONTEXT => "a RexxContext" T1 A4 >A> "a RexxContext" -T1 A4 26 *-* .coactivity~new('.coactivity~yield("a") ; .coactivity~yield("b")')~pipe(.upper|.displayer) +T1 A4 26 *-* .coactivity~new('.coactivity~yield("a") ; .coactivity~yield("b")')~pipe(.upper|.console) T1 A4 >E> .COACTIVITY => "The Coactivity class" T1 A4 >L> ".coactivity~yield("a") ; .coactivity~yield("b")" T1 A4 >A> ".coactivity~yield("a") ; .coactivity~yield("b")" @@ -113,15 +113,15 @@ T1 A4 >M> "NEW" => "a Coactivity" T2 A6 V2 1* >E> .ACTIVITY => "The ACTIVITY class" T1 A4 >E> .UPPER => "The UPPER class" -T1 A4 >E> .DISPLAYER => "The DISPLAYER class" +T1 A4 >E> .CONSOLE => "The CONSOLE class" T2 A6 V2 1* >M> "LOCAL" => "a Directory" T1 A7 V3 >I> Method | with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T2 A6 V2 1* 103 *-* .Activity~local~coactivity = self T1 A7 V3 1* 66 *-* use strict arg follower T2 A6 V2 1* >E> .ACTIVITY => "The ACTIVITY class" -T1 A7 V3 1* >>> "The DISPLAYER class" +T1 A7 V3 1* >>> "The CONSOLE class" T2 A6 V2 1* >M> "LOCAL" => "a Directory" -T1 A7 V3 1* >=> FOLLOWER <= "The DISPLAYER class" +T1 A7 V3 1* >=> FOLLOWER <= "The CONSOLE class" T2 A6 V2 1* >V> SELF => "a Coactivity" T1 A7 V3 1* 67 *-* me = self~new -- create a new pipeStage instance T2 A6 V2 1* >A> "a Coactivity" @@ -157,13 +157,13 @@ T2 A6 V2 1* >O> "<>" => "0" T1 A7 V3 1* >V> ME => "an UPPER" T2 A6 V2 1* >>> "0" -T1 A7 V3 1* >V> FOLLOWER => "The DISPLAYER class" +T1 A7 V3 1* >V> FOLLOWER => "The CONSOLE class" T1 A9 V4 >I> Method | with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A9 V4 1* 81 *-* use strict arg follower -T1 A9 V4 1* >>> "The DISPLAYER class" -T1 A9 V4 1* >=> FOLLOWER <= "The DISPLAYER class" +T1 A9 V4 1* >>> "The CONSOLE class" +T1 A9 V4 1* >=> FOLLOWER <= "The CONSOLE class" T1 A9 V4 1* 82 *-* follower = follower~new -- make sure this is an instance -T1 A9 V4 1* >V> FOLLOWER => "The DISPLAYER class" +T1 A9 V4 1* >V> FOLLOWER => "The CONSOLE class" T1 A10 V5 >I> Method INIT with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A10 V5 1* 61 *-* expose next secondary T1 A10 V5 1* 62 *-* next = .nil @@ -174,18 +174,18 @@ T1 A10 V5 1* >E> .NIL => "The NIL object" T1 A10 V5 1* >>> "The NIL object" T1 A10 V5 1* >=> SECONDARY <= "The NIL object" -T1 A9 V4 1* >M> "NEW" => "a DISPLAYER" -T1 A9 V4 1* >>> "a DISPLAYER" -T1 A9 V4 1* >=> FOLLOWER <= "a DISPLAYER" +T1 A9 V4 1* >M> "NEW" => "a CONSOLE" +T1 A9 V4 1* >>> "a CONSOLE" +T1 A9 V4 1* >=> FOLLOWER <= "a CONSOLE" T1 A9 V4 1* 83 *-* self~append(follower) -- do the chain append logic T1 A9 V4 1* >V> SELF => "an UPPER" -T1 A9 V4 1* >V> FOLLOWER => "a DISPLAYER" -T1 A9 V4 1* >A> "a DISPLAYER" +T1 A9 V4 1* >V> FOLLOWER => "a CONSOLE" +T1 A9 V4 1* >A> "a CONSOLE" T1 A11 V4 1 >I> Method APPEND with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A11 V4 2* 99 *-* expose next T1 A11 V4 2* 100 *-* use strict arg follower -T1 A11 V4 2* >>> "a DISPLAYER" -T1 A11 V4 2* >=> FOLLOWER <= "a DISPLAYER" +T1 A11 V4 2* >>> "a CONSOLE" +T1 A11 V4 2* >=> FOLLOWER <= "a CONSOLE" T1 A11 V4 2* 101 *-* if .nil == next T1 A11 V4 2* >E> .NIL => "The NIL object" T1 A11 V4 2* >V> NEXT => "The NIL object" @@ -194,9 +194,9 @@ T1 A11 V4 2* 101 *-* then T1 A11 V4 2* 101 *-* do -- if we're the end already, just update the next T1 A11 V4 2* 102 *-* next = follower -T1 A11 V4 2* >V> FOLLOWER => "a DISPLAYER" -T1 A11 V4 2* >>> "a DISPLAYER" -T1 A11 V4 2* >=> NEXT <= "a DISPLAYER" +T1 A11 V4 2* >V> FOLLOWER => "a CONSOLE" +T1 A11 V4 2* >>> "a CONSOLE" +T1 A11 V4 2* >=> NEXT <= "a CONSOLE" T1 A11 V4 2* 103 *-* end T1 A9 V4 1* 84 *-* return self -- we're our own return value T1 A9 V4 1* >V> SELF => "an UPPER" @@ -335,7 +335,7 @@ T1 A4 24 *-* call Doers.AddVisibilityFrom(.context) T1 A4 >E> .CONTEXT => "a RexxContext" T1 A4 >A> "a RexxContext" -T1 A4 26 *-* .coactivity~new('.coactivity~yield("a") ; .coactivity~yield("b")')~pipe(.upper|.displayer) +T1 A4 26 *-* .coactivity~new('.coactivity~yield("a") ; .coactivity~yield("b")')~pipe(.upper|.console) T1 A4 >E> .COACTIVITY => "The Coactivity class" T1 A4 >L> ".coactivity~yield("a") ; .coactivity~yield("b")" T1 A4 >A> ".coactivity~yield("a") ; .coactivity~yield("b")" @@ -395,15 +395,15 @@ T1 A4 >M> "NEW" => "a Coactivity" T2 A6 V2 1* >E> .ACTIVITY => "The ACTIVITY class" T1 A4 >E> .UPPER => "The UPPER class" -T1 A4 >E> .DISPLAYER => "The DISPLAYER class" +T1 A4 >E> .CONSOLE => "The CONSOLE class" T2 A6 V2 1* >M> "LOCAL" => "a Directory" T1 A7 V3 >I> Method | with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T2 A6 V2 1* 103 *-* .Activity~local~coactivity = self T1 A7 V3 1* 66 *-* use strict arg follower T2 A6 V2 1* >E> .ACTIVITY => "The ACTIVITY class" -T1 A7 V3 1* >>> "The DISPLAYER class" +T1 A7 V3 1* >>> "The CONSOLE class" T2 A6 V2 1* >M> "LOCAL" => "a Directory" -T1 A7 V3 1* >=> FOLLOWER <= "The DISPLAYER class" +T1 A7 V3 1* >=> FOLLOWER <= "The CONSOLE class" T2 A6 V2 1* >V> SELF => "a Coactivity" T1 A7 V3 1* 67 *-* me = self~new -- create a new pipeStage instance T2 A6 V2 1* >A> "a Coactivity" @@ -439,13 +439,13 @@ T2 A6 V2 1* >O> "<>" => "0" T1 A7 V3 1* >V> ME => "an UPPER" T2 A6 V2 1* >>> "0" -T1 A7 V3 1* >V> FOLLOWER => "The DISPLAYER class" +T1 A7 V3 1* >V> FOLLOWER => "The CONSOLE class" T1 A9 V4 >I> Method | with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A9 V4 1* 81 *-* use strict arg follower -T1 A9 V4 1* >>> "The DISPLAYER class" -T1 A9 V4 1* >=> FOLLOWER <= "The DISPLAYER class" +T1 A9 V4 1* >>> "The CONSOLE class" +T1 A9 V4 1* >=> FOLLOWER <= "The CONSOLE class" T1 A9 V4 1* 82 *-* follower = follower~new -- make sure this is an instance -T1 A9 V4 1* >V> FOLLOWER => "The DISPLAYER class" +T1 A9 V4 1* >V> FOLLOWER => "The CONSOLE class" T1 A10 V5 >I> Method INIT with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A10 V5 1* 61 *-* expose next secondary T1 A10 V5 1* 62 *-* next = .nil @@ -456,18 +456,18 @@ T1 A10 V5 1* >E> .NIL => "The NIL object" T1 A10 V5 1* >>> "The NIL object" T1 A10 V5 1* >=> SECONDARY <= "The NIL object" -T1 A9 V4 1* >M> "NEW" => "a DISPLAYER" -T1 A9 V4 1* >>> "a DISPLAYER" -T1 A9 V4 1* >=> FOLLOWER <= "a DISPLAYER" +T1 A9 V4 1* >M> "NEW" => "a CONSOLE" +T1 A9 V4 1* >>> "a CONSOLE" +T1 A9 V4 1* >=> FOLLOWER <= "a CONSOLE" T1 A9 V4 1* 83 *-* self~append(follower) -- do the chain append logic T1 A9 V4 1* >V> SELF => "an UPPER" -T1 A9 V4 1* >V> FOLLOWER => "a DISPLAYER" -T1 A9 V4 1* >A> "a DISPLAYER" +T1 A9 V4 1* >V> FOLLOWER => "a CONSOLE" +T1 A9 V4 1* >A> "a CONSOLE" T1 A11 V4 1 >I> Method APPEND with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A11 V4 2* 99 *-* expose next T1 A11 V4 2* 100 *-* use strict arg follower -T1 A11 V4 2* >>> "a DISPLAYER" -T1 A11 V4 2* >=> FOLLOWER <= "a DISPLAYER" +T1 A11 V4 2* >>> "a CONSOLE" +T1 A11 V4 2* >=> FOLLOWER <= "a CONSOLE" T1 A11 V4 2* 101 *-* if .nil == next T1 A11 V4 2* >E> .NIL => "The NIL object" T1 A11 V4 2* >V> NEXT => "The NIL object" @@ -476,9 +476,9 @@ T1 A11 V4 2* 101 *-* then T1 A11 V4 2* 101 *-* do -- if we're the end already, just update the next T1 A11 V4 2* 102 *-* next = follower -T1 A11 V4 2* >V> FOLLOWER => "a DISPLAYER" -T1 A11 V4 2* >>> "a DISPLAYER" -T1 A11 V4 2* >=> NEXT <= "a DISPLAYER" +T1 A11 V4 2* >V> FOLLOWER => "a CONSOLE" +T1 A11 V4 2* >>> "a CONSOLE" +T1 A11 V4 2* >=> NEXT <= "a CONSOLE" T1 A11 V4 2* 103 *-* end T1 A9 V4 1* 84 *-* return self -- we're our own return value T1 A9 V4 1* >V> SELF => "an UPPER" @@ -762,16 +762,16 @@ T1 A24 V4 3* >=> DATA <= "A" T1 A24 V4 3* 158 *-* if .nil <> next T1 A24 V4 3* >E> .NIL => "The NIL object" -T1 A24 V4 3* >V> NEXT => "a DISPLAYER" +T1 A24 V4 3* >V> NEXT => "a CONSOLE" T1 A24 V4 3* >O> "<>" => "1" T1 A24 V4 3* >>> "1" T1 A24 V4 3* 158 *-* then T1 A24 V4 3* 158 *-* do T1 A24 V4 3* 159 *-* next~process(data) -- only forward if we have a successor -T1 A24 V4 3* >V> NEXT => "a DISPLAYER" +T1 A24 V4 3* >V> NEXT => "a CONSOLE" T1 A24 V4 3* >V> DATA => "A" T1 A24 V4 3* >A> "A" -T1 A25 V8 >I> Method PROCESS with scope "The DISPLAYER class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex +T1 A25 V8 >I> Method PROCESS with scope "The CONSOLE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A25 V8 1* 579 *-* use strict arg value -- get the data value T1 A25 V8 1* >>> "A" T1 A25 V8 1* >=> VALUE <= "A" @@ -786,7 +786,7 @@ T1 A26 V5 1* >>> "A" T1 A26 V5 1* >=> VALUE <= "A" T1 A26 V5 1* 153 *-* self~write(value) -- send this down the line -T1 A26 V5 1* >V> SELF => "a DISPLAYER" +T1 A26 V5 1* >V> SELF => "a CONSOLE" T1 A26 V5 1* >V> VALUE => "A" T1 A26 V5 1* >A> "A" T1 A27 V5 1 >I> Method WRITE with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex @@ -1008,16 +1008,16 @@ T1 A35 V4 3* >=> DATA <= "B" T1 A35 V4 3* 158 *-* if .nil <> next T1 A35 V4 3* >E> .NIL => "The NIL object" -T1 A35 V4 3* >V> NEXT => "a DISPLAYER" +T1 A35 V4 3* >V> NEXT => "a CONSOLE" T1 A35 V4 3* >O> "<>" => "1" T1 A35 V4 3* >>> "1" T1 A35 V4 3* 158 *-* then T1 A35 V4 3* 158 *-* do T1 A35 V4 3* 159 *-* next~process(data) -- only forward if we have a successor -T1 A35 V4 3* >V> NEXT => "a DISPLAYER" +T1 A35 V4 3* >V> NEXT => "a CONSOLE" T1 A35 V4 3* >V> DATA => "B" T1 A35 V4 3* >A> "B" -T1 A36 V8 >I> Method PROCESS with scope "The DISPLAYER class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex +T1 A36 V8 >I> Method PROCESS with scope "The CONSOLE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A36 V8 1* 579 *-* use strict arg value -- get the data value T1 A36 V8 1* >>> "B" T1 A36 V8 1* >=> VALUE <= "B" @@ -1032,7 +1032,7 @@ T1 A37 V5 1* >>> "B" T1 A37 V5 1* >=> VALUE <= "B" T1 A37 V5 1* 153 *-* self~write(value) -- send this down the line -T1 A37 V5 1* >V> SELF => "a DISPLAYER" +T1 A37 V5 1* >V> SELF => "a CONSOLE" T1 A37 V5 1* >V> VALUE => "B" T1 A37 V5 1* >A> "B" T1 A38 V5 1 >I> Method WRITE with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex @@ -1231,13 +1231,13 @@ T1 A45 V4 3* 173 *-* expose next secondary T1 A45 V4 3* 174 *-* if .nil <> next T1 A45 V4 3* >E> .NIL => "The NIL object" -T1 A45 V4 3* >V> NEXT => "a DISPLAYER" +T1 A45 V4 3* >V> NEXT => "a CONSOLE" T1 A45 V4 3* >O> "<>" => "1" T1 A45 V4 3* >>> "1" T1 A45 V4 3* 174 *-* then T1 A45 V4 3* 174 *-* do T1 A45 V4 3* 175 *-* next~eof -- only forward if we have a successor -T1 A45 V4 3* >V> NEXT => "a DISPLAYER" +T1 A45 V4 3* >V> NEXT => "a CONSOLE" T1 A46 V5 >I> Method EOF with scope "The PIPESTAGE class" in package d:\local\Rexx\ooRexx\svn\sandbox\jlf\samples\pipeline\pipe.rex T1 A46 V5 1* 173 *-* expose next secondary T1 A46 V5 1* 174 *-* if .nil <> next Modified: sandbox/jlf/samples/pipeline/pipe.rex =================================================================== --- sandbox/jlf/samples/pipeline/pipe.rex 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/pipeline/pipe.rex 2011-07-24 22:13:36 UTC (rev 7078) @@ -269,15 +269,6 @@ /******************************************************************************/ --- Provide services that depend on extensions --- Will be extended in a separate file -::class pipeExtensions public - -::method available class -return self~hasMethod("installed") - - -/******************************************************************************/ ::class pipeProfiler public subclass Profiler ::method instrument class @@ -436,12 +427,10 @@ if "numeric"~caselessAbbrev(a, 1) then do ; criteria~append(.array~of("strict=", .false)) ; iterate ; end if "strict"~caselessAbbrev(a, 3) then do ; criteria~append(.array~of("strict=", .true)) ; iterate ; end end - if a~hasMethod("doer") then do - if .pipeExtensions~available then do - function = .pipeExtensions~makeFunctionDoer(a) - criteria~append(.array~of("sortBy", function)) - iterate - end + if a~hasMethod("functionDoer") then do + function = a~functionDoer("use arg value, index") + criteria~append(.array~of("sortBy", function)) + iterate end unknown~append(a) end @@ -774,9 +763,9 @@ iterate end end - if a~hasMethod("doer") then do + if a~hasMethod("functionDoer") then do if doer <> .nil then raise syntax 93.900 array(self~class~id ": Only one partition expression is supported") - doer = .pipeExtensions~makeFunctionDoer(a) + doer = a~functionDoer("use arg value, index") iterate end unknown~append(a) @@ -943,7 +932,7 @@ /******************************************************************************/ -::class displayer subclass pipeStage public +::class console subclass pipeStage public ::constant indexSeparator "|" ::method init @@ -992,12 +981,10 @@ actions~append(.array~of("displayString", a)) iterate end - if a~hasMethod("doer") then do - if .pipeExtensions~available then do - function = .pipeExtensions~makeFunctionDoer(a) - actions~append(.array~of("displayExpression", function)) - iterate - end + if a~hasMethod("functionDoer") then do + function = a~functionDoer("use arg value, index") + actions~append(.array~of("displayExpression", function)) + iterate end unknown~append(a) end Modified: sandbox/jlf/samples/pipeline/pipe_extension.cls =================================================================== --- sandbox/jlf/samples/pipeline/pipe_extension.cls 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/pipeline/pipe_extension.cls 2011-07-24 22:13:36 UTC (rev 7078) @@ -5,16 +5,16 @@ --::options trace i /* -I wanted to support something like that : "a"|.upper|.displayer +I wanted to support something like that : "a"|.upper|.console where the first '|' is an overriden operator which injects any object in the pipe. But can't do that because : - extension does not override existing methods ('|' already exists on .String). - even if '|' overriding was possible, the injection wouldn't be possible from the overriden '|' because it's too early... The expression above is in fact - ("a"|.upper)|.displayer - so an injection made by ("a"|.upper) wouldn't reach |.displayer. + ("a"|.upper)|.console + so an injection made by ("a"|.upper) wouldn't reach |.console. So I added the 'pipe' method which injects the object in the pipe : -"a"~pipe(.upper|.displayer) +"a"~pipe(.upper|.console) */ ::extension Object @@ -33,62 +33,6 @@ /******************************************************************************/ --- This class is defined in pipe.rex, to make it visible without requiring the --- current file (I don't want to make pipe.rex dependent on extensions). --- There is a test at runtime to see if 'installed' is present on the class. - -::extension pipeExtensions - -::method installed class - return .true - --- A function always takes two parameters : value and index. They are automatically declared. --- A function always return a result. The "return" instruction is automatically inserted, if missing. --- Beware ! The insertion of 'return' is not robust. More work needed here... --- A function is not allowed to run a command. -::method makeFunctionDoer public class - use strict arg doable - if doable~isA(.RexxContextualSource) then do - source = doable~source~strip - if source <> "" then do - if source~caselessPos("return ") == 0 then do - -- If the source is multiline, then some ';' have been inserted to replace the newlines. - -- Must remove the first and final ';', if any. - -- If there are still ';' in the source then 'return' can't be inserted (the source is probably wrong). - do until changed == .false - start = 1 ; length = source~length ; changed = .false - if source~left(1) == ";" then do ; start=2 ; length -= 1 ; changed = .true ; end - if source~right(1) == ";" then do ; length -= 1 ; changed = .true ; end - source = source~substr(start, length) - end - if source~pos(";") <> 0 then raise syntax 93.900 array("This is not an expression :" source) - source = "return" source - end - source = "use arg value, index;" source - end - doable~source = source - end - doer = doable~doer - if doer~hasMethod("setSecurityManager") then doer~setSecurityManager(.CommandNotAllowed~new) -- A doer can be a message, which has not this method - return doer - --- An action always takes two parameters : value and index. They are automatically declared. --- 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 doable - if doable~isA(.RexxContextualSource) then do - source = doable~source - if source~strip <> "" then do - source = "use arg value, index;" source - end - doable~source = source - end - doer = doable~doer - return doer - - -/******************************************************************************/ -- Convenience notation : -- .index_value[index, value, index, value, ...] -- .value_index[value, index, value, index, ...] @@ -123,17 +67,6 @@ /******************************************************************************/ -::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. @@ -142,16 +75,10 @@ ::method initOptions expose supplier - supplier = .nil - unknown = .array~new - do a over arg(1, "a") - if supplier <> .nil then raise syntax 93.900 array(self~class~id ": Only one producer is supported") - producer = a - if producer~hasMethod("doer") then producer = .pipeExtensions~makeFunctionDoer(producer)~do - if \producer~hasMethod("supplier") then supplier = .array~of(producer) -- for convenience, accept a non-supplier - supplier = producer~supplier - end - forward class (super) arguments (unknown) -- forward the initialization to super to process the unknown options + use strict arg producer + if producer~hasMethod("doer") then producer = producer~doer~do + if \producer~hasMethod("supplier") then producer = .array~of(producer) -- for convenience, accept a non-supplier + supplier = producer~supplier ::method eof expose supplier @@ -213,8 +140,9 @@ end if a~hasMethod("doer") then do if doer <> .nil then raise syntax 93.900 array(self~class~id ": Only one producer is supported") - if allowCommand then doer = .pipeExtensions~makeActionDoer(a) - else doer = .pipeExtensions~makeFunctionDoer(a) + if allowCommand, a~hasMethod("actionDoer") then doer = a~actionDoer("use arg value, index") + else if a~hasMethod("functionDoer") then doer = a~functionDoer("use arg value, index") + else doer = a~doer iterate end unknown~append(a) @@ -355,15 +283,9 @@ ::method initOptions expose doer - doer = .nil - unknown = .array~new - do a over arg(1, "a") - if doer <> .nil then raise syntax 93.900 array(self~class~id ": Only one filter is supported") - if a~hasMethod("doer") then do ; doer = .pipeExtensions~makeFunctionDoer(a) ; iterate ; end - unknown~append(a) - end - if doer == .nil then raise syntax 93.900 array(self~class~id ": No filter specified") - forward class (super) arguments (unknown) -- forward the initialization to super to process the unknown options + use strict arg filter + if filter~hasMethod("functionDoer") then doer = filter~functionDoer("use arg value, index") + else doer = filter~doer ::method process Modified: sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt =================================================================== --- sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt 2011-07-24 22:04:03 UTC (rev 7077) +++ sandbox/jlf/samples/pipeline/pipe_extension_test.output.txt 2011-07-24 22:13:36 UTC (rev 7078) @@ -1,7 +1,7 @@ -- The coactivity yields two results. --- The hello outputs are not in the pipeline flow (not displayed by the .displayer). -.coactivity~new{ echo hello ; .yield[a] ; say hello ; .yield[b] }~pipe(.upper|.displayer) +-- The hello outputs are not in the pipeline flow (not displayed by the .console). +.coactivity~new{ echo hello ; .yield[a] ; say hello ; .yield[b] }~pipe(.upper|.console) HELLO 1 : A HELLO @@ -9,14 +9,14 @@ -- A collection can be sorted by value (default) -.array~of(b, a, c)~pipe(.sort byValue | .displayer) +.array~of(b, a, c)~pipe(.sort byValue | .console) 2 : A 1 : B 3 : C -- ...or by index -.array~of(b, a, c)~pipe(.sort byIndex | .displayer) +.array~of(b, a, c)~pipe(.sort byIndex | .console) 1 : B 2 : A 3 : C @@ -25,14 +25,14 @@ -- ...ascending (default) -- The order of options is important : a value option is impacted only by the preceding options -- This is because several value options can be specified, and a sort is made for each. -.array~of(b, a, c)~pipe(.sort ascending byValue | .displayer) +.array~of(b, a, c)~pipe(.sort ascending byValue | .console) 2 : A 1 : B 3 : C -- ...descending -.array~of(b, a, c)~pipe(.sort descending byValue | .displayer) +.array~of(b, a, c)~pipe(.sort descending byValue | .console) 3 : C 1 : B 2 : A @@ -41,14 +41,14 @@ -- ...by index descending -- The order of options is important : an index option is impacted only by the preceding options. -- This is because several index options can be specified, and a sort is made for each. -.array~of(b, a, c)~pipe(.sort descending byIndex | .displayer) +.array~of(b, a, c)~pipe(.sort descending byIndex | .console) 3 : C 2 : A 1 : B -- ...caseless (stable by default) -.array~of("bb", "AA", "bB", "Aa", "Bb", "aA", "BB", "aa")~pipe(.sort caseless byValue | .displayer) +.array~of("bb", "AA", "bB", "Aa", "Bb", "aA", "BB", "aa")~pipe(.sort caseless byValue | .console) 2 : AA 4 : Aa 6 : aA @@ -60,7 +60,14 @@ -- ...caseless quickSort (unstable) -.array~of("bb", "AA", "bB", "Aa", "Bb", "aA", "BB", "aa")~pipe(.sort caseless quickSort byValue | .displayer) +-- No difference bewteen stable and unstable ? yes, see commit 6275 in interpreter/memory/setup.cpp : +-- // there have been some problems with the quick sort used as the default sort, so map everything +-- // to the stable sort. The stable sort, in theory, uses more memory, but in practice, this is not true. +-- defineKernelMethod(CHAR_SORT ,TheArrayBehaviour, CPPM(RexxArray::stableSortRexx), 0); +-- defineKernelMethod(CHAR_SORTWITH ,TheArrayBehaviour, CPPM(RexxArray::stableSortWithRexx), 1); +-- defineKernelMethod(CHAR_STABLESORT ,TheArrayBehaviour, CPPM(RexxArray::stableSortRexx), 0); +-- defineKernelMethod(CHAR_STABLESORTWITH ,TheArrayBehaviour, CPPM(RexxArray::stableSortWithRexx), 1); +.array~of("bb", "AA", "bB", "Aa", "Bb", "aA", "BB", "aa")~pipe(.sort caseless quickSort byValue | .console) 2 : AA 4 : Aa 6 : aA @@ -73,7 +80,7 @@ -- Sort descending with a comparator. -- The DescendingComparator use the default CompareTo, which is made on values. -.array~of(b, a, c)~pipe(.sortWith[.DescendingComparator~new] | .displayer) +.array~of(b, a, c)~pipe(.sortWith[.DescendingComparator~new] | .console) 3 : C 1 : B 2 : A @@ -83,7 +90,7 @@ .array~of("c:2", "b:2", "A:2", "c:1", "a:1", "B:1", "C:3")~pipe(, .sortWith[.InvertingComparator~new(.CaselessColumnComparator~new(3,1))] |, .sortWith[.CaselessColumnComparator~new(1,1)] |, - .displayer, + .console, ) 3 : A:2 5 : a:1 @@ -95,14 +102,14 @@ -- Do something for each item (no returned value). -.array~of(1, 2, 3)~pipe(.do {say 'value='value 'index='index} | .displayer) +.array~of(1, 2, 3)~pipe(.do {say 'value='value 'index='index} | .console) value=1 index=an Array value=2 index=an Array value=3 index=an Array -- Do something for each item (the returned result replaces the item's value). -.array~of(1, 2, 3)~pipe(.do {return 2*value} | .displayer) +.array~of(1, 2, 3)~pipe(.do {return 2*value} | .console) 1 : 2 1 : 4 1 : 6 @@ -110,7 +117,7 @@ -- 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) +.array~of(1, 2, 3)~pipe(.inject {value*10} pushIndex append | .console) 1 : 1 1|1 : 10 2 : 2 @@ -120,7 +127,7 @@ -- 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*10, value*20)} pushIndex append | .displayer) +.array~of(1, 2, 3)~pipe(.inject {.array~of(value*10, value*20)} pushIndex append | .console) 1 : 1 1|1 : 10 1|2 : 20 @@ -136,18 +143,18 @@ -- 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*10} pushIndex recursive.0 | .console) 1|1 : 10 2|1 : 20 3|1 : 30 -.array~of(1, 2, 3)~pipe(.inject {value*20} pushIndex recursive.1| .displayer) +.array~of(1, 2, 3)~pipe(.inject {value*20} pushIndex recursive.1| .console) 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) +.array~of(1, 2, 3)~pipe(.inject {value*30} pushIndex recursive.2 | .console) 1|1 : 30 1|1|1 : 900 1|1|1|1 : 27000 @@ -165,7 +172,7 @@ use arg n if n < 0 then return if n == 0 then return 1 - return n * .context~executable~call(n - 1)} | .displayer) + return n * .context~executable~call(n - 1)} | .console) 1 : 1 1 : 1 1 : 2 @@ -183,23 +190,23 @@ .file~new(installdir())~listFiles~pipe(, .select {value~name~caselessPos('rexx') <> 0} |, .take 15 |, - .displayer, + .console, ) -153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.cls -154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.dll -155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.exp -156 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.lib -157 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.map -158 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.obj -159 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.pdb -187 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.dll -188 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exe -189 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exp -190 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.img -191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.lib -192 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.map -193 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.obj -194 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.pdb +152 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.cls +153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.dll +154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.exp +155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.lib +156 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.map +157 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.obj +184 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.dll +185 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exe +186 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exp +187 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.img +188 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.lib +189 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.map +190 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.obj +191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.res +192 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\RexxActivation.obj -- Select files in the installation directory, whose name contains "rexx" , sorted by file size. @@ -209,23 +216,23 @@ .select {value~name~caselessPos('rexx') <> 0} |, .sortWith[.MessageComparator~new("length/N")] |, .take 15 |, - .displayer, + .console, ) -241 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.exp -155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.exp -242 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.lib -156 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.lib -189 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exp -191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.lib -200 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.exp -195 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.res -153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.cls -201 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.lib -223 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexximage.obj -210 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\RexxCompiler.obj -219 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxhide.obj -235 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxpaws.obj -193 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.obj +216 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexximage.obj +232 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.exp +154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.exp +233 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.lib +204 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\RexxCompiler.obj +155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.lib +186 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exp +213 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxhide.obj +227 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxpaws.obj +190 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.obj +188 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.lib +196 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.exp +191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.res +152 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.cls +197 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.lib -- Same as above, but simpler... You can sort directly by length, no need of MessageComparator @@ -233,23 +240,23 @@ .select {value~name~caselessPos('rexx') <> 0} |, .sort {value~length} |, .take 15 |, - .displayer, + .console, ) -241 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.exp -155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.exp -242 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.lib -156 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.lib -189 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exp -191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.lib -200 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.exp -195 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.res -153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.cls -201 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.lib -223 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexximage.obj -210 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\RexxCompiler.obj -219 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxhide.obj -235 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxpaws.obj -193 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.obj +216 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexximage.obj +232 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.exp +154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.exp +233 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.lib +204 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\RexxCompiler.obj +155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.lib +186 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exp +213 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxhide.obj +227 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxpaws.obj +190 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.obj +188 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.lib +196 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.exp +191 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.res +152 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.cls +197 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.lib -- Sort by file size, then by file extension (with only one .sort pipestage) @@ -257,28 +264,28 @@ .select {value~name~caselessPos('rexx') <> 0} |, .sort {value~length} {filespec('e', value~name)} |, .take 15 |, - .displayer, + .console, ) -153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.cls -154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.dll -199 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.dll -240 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.dll -187 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.dll -221 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexximage.exe -217 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxhide.exe -205 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxc.exe -188 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exe -233 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxpaws.exe -241 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxutil.exp -155 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\orexxole.exp -189 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.exp -200 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexxapi.exp -190 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32dbg\rexx.img +152 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.cls +153 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.dll +195 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.dll +231 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.dll +184 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.dll +214 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexximage.exe +211 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxhide.exe +200 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxc.exe +185 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exe +225 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxpaws.exe +232 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxutil.exp +154 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\orexxole.exp +186 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.exp +196 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexxapi.exp +187 : d:\local\Rexx\ooRexx\svn\sandbox\jlf\trunk\Win32rel\rexx.img -- All instance methods of the context. -- Notice that the default sort by value is useless here... Must sort by index. -.context~instanceMethods~pipe(.sort byIndex | .displayer) +.context~instanceMethods~pipe(.sort byIndex | .console) : a Method : a Method <> : a Method @@ -332,7 +339,7 @@ .context~instanceMethods~pipe(, .select {value~isPrivate} |, .sort byIndex |, - .displayer, + .console, ) RUN : a Method SETMETHOD : a Method @@ -345,7 +352,7 @@ .array~of(.RexxContext, .Package, .Method)~pipe(, .inject {value~instanceMethods(value~class)} append pushIndex |, .sort byIndex |, - .displayer, + .console, ) 1 : The RexxContext class 1|<> : a Method @@ -436,7 +443,7 @@ .select {value~id~caselessAbbrev('R') <> 0} |, .inject {value~methods(value)} append pushIndex |, .sort byIndex |, - .displayer, + .console, ) RELATION : The Relation class RELATION|ALLAT : a Method @@ -482,7 +489,6 @@ REXXCONTEXTUALSOURCE|COPY : a Method REXXCONTEXTUALSOURCE|PACKAGE : a Method REXXCONTEXTUALSOURCE|SOURCE : a Method -REXXCONTEXTUALSOURCE|SOURCE= : a Method REXXQUEUE : The RexxQueue class REXXQUEUE|DELETE : a Method REXXQUEUE|EMPTY : a Method @@ -508,10 +514,10 @@ -- All packages that are visible from current context, including the current package (source of the pipeline). .context~package~pipe(, .inject {value~importedPackages} recursive append pushIndex |, - .displayer index.15, - {' '~copies(index~items)}, - {.file~new(value~name)~name}, - newline, + .console index.15, + {' '~copies(index~items)},... [truncated message content] |