Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

[r7909]: sandbox / jlf / samples / extension / std / doers-std.cls Maximize Restore History

Download this file

doers-std.cls    145 lines (118 with data), 5.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
This script works with a standard ooRexx, but has drawbacks compared to doers.cls.
*/
--::options trace i
-----------------------------------------------------------------------------
/*
Extract from rexxref, .Routine~new :
The context allows the created routine to inherit class and routine lookup scope from another source. If
specified, context can be a Method object, a Routine object, or a Package object. If not specified, the
newly created method will inherit the class and routine search scope from the caller of new method.
So, by default, any routine created by StringDoer will have a lookup scope limited to the doers package,
because the routines are created from here, not from the caller's package.
StringDoer~doer accepts a context parameter to let the caller pass its own lookup scope, but this is
tedious to pass it explicitely.
That's why I provide this routine which lets see from doers the same packages/methods/routines as the caller.
Usage from caller's package :
call Doers.AddVisibilityFrom(.context)
Note : this is a temporary workaround. The good approach is to add support for first-class
expressions/instructions that are parsed in place, instead of being parsed by StringDoer..
https://sourceforge.net/mailarchive/message.php?msg_id=19912031
*/
::routine Doers.AddVisibilityFrom public
use strict arg package -- can be a .Package or a .RexxContext
if package~isA(.RexxContext) then package = package~package
do p over package~importedPackages
.context~package~addPackage(p)
end
classes = package~classes
do c over classes
.context~package~addClass(c, classes[c])
end
routines = package~routines
do r over routines
.context~package~addRoutine(r, routines[r])
end
-----------------------------------------------------------------------------
-- Mixins.
-- A Doer is an object which knows how to execute itself (understands "do")
::class RoutineDoer mixinclass Object public
::method init
-- Enhancement by delegation (wrapper) when ~enhanced can't be used
expose routine
use arg routine=.nil
::method doer
use strict arg context=.nil
if context <> .nil then raise syntax 93.900 array ("Context not supported")
return self
::method needsObject
return .false -- No need to pass an object as first argument when calling do or doWith
::method do
expose routine -- In some cases, the "real" routine is encapsulated
if var("routine"), routine <> .nil then self = routine
self~callWith(arg(1,"a"))
if var("result") then return result
::method doWith
expose routine -- In some cases, the "real" routine is encapsulated
use strict arg array
if var("routine"), routine <> .nil then self = routine
self~callWith(array)
if var("result") then return result
/*
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 ?)
*/
::class MethodDoer mixinclass Object public
::method doer
use strict arg context=.nil
if context <> .nil then raise syntax 93.900 array ("Context not supported")
return self
::method needsObject
return .true -- Must pass an object as first argument when calling do or doWith
::method do
use strict arg object, ...
object~run(self, "a", arg(2,"a"))
if var("result") then return result
::method doWith
use strict arg object, array
object~run(self, "a", array)
if var("result") then return result
::class StringDoer mixinclass Object public
::method doer
use strict arg context=.nil
parse var self word1 rest
-- When the source string contains a single word without '(', it's a message name
if rest == "" & word1~pos("(") == 0 then do
if context <> .nil then raise syntax 93.900 array ("Context not supported")
return self
end
if word1~caselessEquals("::method") then do
if context == .nil then return .Method~enhanced(.MethodDoer~methods(.nil), "", rest)
if context~isA(.RexxContext) then context = context~package
return .Method~enhanced(.MethodDoer~methods(.nil), "", rest, context)
end
if word1~caselessEquals("::routine") then do
if context == .nil then return .Routine~enhanced(.RoutineDoer~methods(.nil), "", rest)
if context~isA(.RexxContext) then context = context~package
return .Routine~enhanced(.RoutineDoer~methods(.nil), "", rest, context)
end
-- Routine by default
-- To support extended classes, must convert self to a "real" string
-- (if self is an ExtendedString then .Routine~new will not accept it).
if context == .nil then return .Routine~enhanced(.RoutineDoer~methods(.nil), "", self~string)
if context~isA(.RexxContext) then context = context~package
return .Routine~enhanced(.RoutineDoer~methods(.nil), "", self~string, context)
::method needsObject
return .true -- Must pass an object as first argument when calling do or doWith
::method do
use strict arg object, ...
-- ~sendWith doesn't accept a subclass of String : must convert self to a String
object~sendWith(self~string, arg(2,"a"))
if var("result") then return result
::method doWith
use strict arg object, array
-- ~sendWith doesn't accept a subclass of String : must convert self to a String
object~sendWith(self~string, array)
if var("result") then return result