如何从一系列函数中检索函数并调用它

时间:2014-03-25 13:15:13

标签: rebol rebol3

我正在尝试在Rebol 3中创建函数调度程序,以便程序接收的每个字符串都有一个要调用的相关函数。

例如:

handlers: make map! [
  "foo" foo-func
  "bar" bar-func
]

其中foo-funcbar-func是函数:

foo-func: func [ a b ] [ print "foo" ]
bar-func: func [ a b ] [ print "bar" ]

这个想法是select从字符串开始的函数,所以:

f: select handlers "foo"

这样执行f与执行foo-func相同,然后使用一些参数调用f

f param1 param2

我尝试引用map!中的字词,或使用get-words但没有成功。

在控制台上使用get-word!,无需通过map!就可以了:

>> a: func [] [ print "Hello world!" ]
>> a
Hello world!
>> b: :a
>> b
Hello world!

任何帮助表示感谢。

4 个答案:

答案 0 :(得分:5)

select handlers "foo"只能得到foo-func

这个词
f: select handlers "foo"
probe f   ;will get: foo-func

您需要获取其内容:

f: get f
f 1 2    ;will print "foo"

或更紧凑:

f: get select handlers "foo"

答案 1 :(得分:4)

地图中的

foo-func只是一个未评估的单词

>> type? select handlers "foo"
== word!

首先应创建函数,然后减少块,用于创建处理程序映射,以便

handlers: make map! reduce [
   "foo" :foo-func
   "bar" :bar-func
]

然后你在地图中有功能

>> type? select handlers "foo"
== function!

答案 2 :(得分:4)

实际上对地图中的函数的引用更好,而不是引用该函数的单词。如果您存储一个单词,那么您必须确保该单词绑定到一个对该函数有引用的对象,如下所示:

handlers: object [
    foo-func: func [ a b ] [ print "foo" ]
    bar-func: func [ a b ] [ print "bar" ]
]

handler-names: map [
    "foo" foo-func
    "bar" bar-func
]

apply get in handlers select handler-names name args

但是如果您只是在地图中引用了该功能,则不必进行双重间接,您的代码如下所示:

handlers: map reduce [
    "foo" func [ a b ] [ print "foo" ]
    "bar" func [ a b ] [ print "bar" ]
]

apply select handlers name args

更清洁的代码,也更高效。或者如果你足够小心,就像这样:

handlers/(name) a b

如果你希望代码在没有处理程序的情况下什么都不做的话,上面的路径方法也会起作用 - 在你有可选处理程序的情况下很常见,例如在GUI中。

您甚至可以使用不同的键名对同一个函数进行多次引用。您不必为单词分配功能,它们只是值。您还可以使用路径方法首先收集处理程序,保存reduce

handlers: make map! 10  ; preallocate as many entries as you expect
handlers/("foo"): func [ a b ] [ print "foo" ]
handlers/("bar"): func [ a b ] [ print "bar" ]
handlers/("baz"): select handlers "bar"  ; multiple references

该路径语法只是调用poke的另一种方式,但有些人更喜欢它。我们必须将字符串值放在parens中,因为(希望是临时的)语法冲突,但在这些parens中,字符串键起作用。它是do selectpoke的更快替代方案。

答案 3 :(得分:2)

尝试:     ....     f:选择处理程序" foo"     ....