[ALLY] REBOL Modules Doc Re:
From: rebol:techscribe at: 3-Aug-2000 1:07
Hi Carl,
I like your module specification. It appears to be a useful tool for
complex scripts. A few questions.
A) Inheritance
Question 1:
Given your example:
example: make module! [
title: "Example module"
version: 1.0.0
export: [do-it]
][
data: [block of local data]
do-it: does [probe data]
]
do modules support inheritance like objects:
example-2: make example [
title: "Example 2 module"
version: 1.0.0
export: [do-it-as-well]
][
data-2: [block of additional data]
do-it-as-well: does [probe data probe data-2]
]
a) Can I now say:
example-2/do-it
b) If a module can inherit a parent module, what kind of permissions are
effective for the descendant module?
Question 2:
If the answer to question 1a) is "YES", then given the parent module
parent-module: make module! [
title: "Parent module"
version: 1.0.0
export: [do-it set-it]
][
data: [block of local data]
do-it: does [probe data]
set-it: func [some-data] [ insert block some-data ]
]
and the descendant module
descendant-module: make module! [
title: "Descendant module"
version: 1.0.0
export: []
][
set-parent-block: does [ set-it "descendant's data." ]
]
if I evaluate
>> descendant-module/set-parent-block
will the parent-module's data block be effected, or will an independent
copy of the data block be effected that is local to descendant-module? I.e.
once set-parent-block in the descendant module has been evaluated, will
>> parent-module/do-it
display the "descendant's data." string as part of parent-module's data
block, or will this string only be displayed if I evaluate
>> descendant-module/do-it
Question 3:
If a descendant module shares the parent module's context (i.e.
parent-module/do-it will display a block that includes the string
descendant's data.
), then can you include the following functionality?
descendant-module make remote-module! [
title: "Descendant module"
version: 1.0.0
url: http://www.rebol-remote-module-server.com/
export: []
][
set-parent-block: does [ set-it "descendant's data." ]
]
such that evaluating
>> descendant-module/set-parent-block
will connect over the Internet to the remote parent module and modify the
data block that is stored in the RAM of the remote machine?
Or am I dreaming? Message-based module inheritance over the Internet?
Based on the pending module enhancement and REBOL's current messaging
features, we need to add only two more words: the make-able type
remote-module! and the addition of url as a module header field:
local-module make remote-module! [
title: "Client Module"
version: 1.0.0
url: http://www.rebol-remote-module-server.com/
export: []
][
]
This would be quite useful.
A simple chat type application, for instance, could be easily implemented.
The chat client could look like this:
The Chat Client
===============
chat-client-module: make remote-module! [
title: "Chat Client Module"
version: 1.0.0
url: http://www.rebol-chat-server.com/
export: []
][
userid: none
login: func [my-user-id] [
userid: my-userid
signup userid
]
chat: does [
forever [
either input? [
post-message userid input
] [
if new-messages? userid [print get-messages userid]
]
]
]
]
>> do chat-client-module.r ;- or chat-client.rm?
== module
>> signup "me" "chat-room-1"
== true
>> chat
given a chat server available on a remote machine that may be implemented as:
The Chat Server
===============
chat-server-module: make module! [
title: "Chat Server Module"
version: 1.0.0
export: [ signup post-message get-messages new-messages? ]
][
chat-db: [
chat-room-1 [
users []
messages []
message-pending []
]
chat-room-2 [
users []
messages []
message-pending []
]
chat-room-3 [
users []
messages []
message-pending []
]
]
signup: func [userid chat-room] [
append chat-db/:chat-room userid
]
new-message: func [chat-room] [
chat-db/:chat-room/message-pending: copy chat-db/:chat-room/users
]
post-message: func [userid chat-room message ] [
if found? find chat-db/:chat-room/users userid [
append chat-db/:chat-room/messages rejoin [userid ": " message]
new-message chat-room
]
]
new-messages?: func [ userid chat-room ] [
found? find chat-db/:chat-room/message-pending userid
]
get-messages: func [userid chat-room /local user] [
if all [
found? find chat-db/:chat-room/users userid
user: new-messages? userid chat-room
]
[
remove user
chat-db/:chat-room/messages
]
]
]
The neat thing about the module feature is that a different site may
implement a different, more stable or capable chat server, and the same,
unmodified chat client could have access to the improved capabilities,
provided that the improved chat server continues to support the same public
interface as the old one. Additional interface functions could be used by
more advanced chat clients.
Your module proposal is only "a few" lines of code away from remote
capabilities. Do you think it is possible to extend your specification to
include this?
B) Can features be added to a module, such that a module may selectively
expose additional functions, if asked to do so by an authorized client?
i.e
authentication-example: make module! [
title: ...
authenticate: true
export: [ authenticate ... ]
authenticated-export: [ authenticated-function ]
][
authorized-clients: ["some-userid" "some-password"
"some-other-userid" "some-other-password"
]
authenticate: func [userid password] [
foreach [user pass] authorized-clients [
if (reduce [user pass]) = (reduce [userid password]) [
return true
]
]
return false
]
authenticated-function: does [
print "only accessable to authenticated modules."
]
]
client: make module! [
title: ....
authorization-id: none
userid: "some-userid"
password: "some-password"
][
authentication-example/authenticated-function
]
Explanation:
When client attempts to evaluate authentication-example's
authenticated-function, authentication-example retrieves the fields userid
and password from client and uses the user-supplied authenticate function
to determine if the module is an authorized module.
If so, authentication-example issues a unique authorization-id and reports
it to client. This authorization-id will remain valid throughout this
session. Based on this authorization-id, authentication-example permits
client to evaluate its authenticated-function, which is any function that
is listed in authentication-export.
When client's module is garbage-collected the module authentication-example
forgets
the authorization-id it issued to client.
B) would be a nice extension to A).
Can't wait to hear from you ... ;-).
At 01:24 PM 7/31/00 -0700, you wrote:
>Jim just reminded me that I promised to say a few words about REBOL
Modules here on the ally list. I'll do better than that: Here's a short
document that describes REBOL modules. Take a look.
>-Carl
>
>Attachment Converted: "c:\eudora\attach\modules.htm"
>
;- Elan [ : - ) ]
author of REBOL: THE OFFICIAL GUIDE
REBOL Press: The Official Source for REBOL Books
http://www.REBOLpress.com
visit me at http://www.TechScribe.com