如何使用字符串名称调用对象函数

发布于 2025-01-03 06:51:26 字数 273 浏览 0 评论 0原文

知道为什么以下不起作用吗? (R3)

o: make object! [
    foo: does [do "bar"]
    bar: does [print "hello from bar"]
]

o/foo
** Script error: bar has no value
** Where: catch either -apply- do foo
** Near: catch/quit either var [[do/next data var]] [data]

Any idea why the following doesn't work? (R3)

o: make object! [
    foo: does [do "bar"]
    bar: does [print "hello from bar"]
]

o/foo
** Script error: bar has no value
** Where: catch either -apply- do foo
** Near: catch/quit either var [[do/next data var]] [data]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

多像笑话 2025-01-10 06:51:26

试试这个:

o: make object! [
    foo: does [do get bind load "bar" self]
    bar: does [print "hello from bar"]
]
o/foo ;this will work

您需要 BINDing,因为您的“栏”位于对象中,而不是在全局范围内。

也检查一下:

my-func: does [print "ok"]
o: make object! [
    foo: does [do "my-func"]
    bar: does [print "hello from bar"]
]
o/foo ;this will work too

您需要加载它,因为它是一个字符串,但它必须是一个要绑定的单词。
所以这些也可以工作(将它们放入你的对象中):

do get bind to-word "bar" self

或者

do get bind 'bar self

Try this:

o: make object! [
    foo: does [do get bind load "bar" self]
    bar: does [print "hello from bar"]
]
o/foo ;this will work

You need that BINDing because your "bar" lives in the object, not in global scope.

Check this out as well:

my-func: does [print "ok"]
o: make object! [
    foo: does [do "my-func"]
    bar: does [print "hello from bar"]
]
o/foo ;this will work too

You need to LOAD it because it is a string, but it has to be a word to be BINDed.
So these will work too (put them in your object):

do get bind to-word "bar" self

or

do get bind 'bar self
千寻… 2025-01-10 06:51:26

没有范围!?

“self/bar”之所以无法知道在哪里可以找到“BAR”,是因为Rebol 中没有作用域(至少在传统的 CS 含义中没有)。

Rebol 中的单词只有在静态绑定到上下文后才有意义。当你“制作一个物体”时,这种情况会自动发生,所以很多人甚至在使用多年后都没有意识到这一点。

以下是创建对象(也称为上下文)时的(松散的)步骤。

  • 它选取其规范中的所有根集单词(在本例中为 [FOO: BAR:] )

  • 将它们添加到其当前的内部单词(SELF:默认情况下,如果您使用对象作为基础,则更多)

  • 然后将块中的所有单词(分层)绑定到它添加到其规范中的那些设置词。

  • 执行块。

所以你看,一旦你执行这个块就太晚了,这些单词已经被赋予了它们的含义,这允许解释器询问它们的值(这可能会触发表达式求值,因此 REBOL 中的 E)。

全局的,因为所有的东西都真正执行过一次。

DO 和 LOAD 无法自动绑定到除全局上下文之外的任何内容...因为不存在像传统 OOP 和命令式语言中那样的“当前上下文”(请记住,没有范围)。实际上,一旦执行,该信息就不再存在,除非您将“当前”上下文绑定到一个单词...这就是“SELF”所做的,但要绑定它必须已经加载,在执行时一个字符串,从未出现过。

无能的函数

我最后会补充一点,乍一看可能并不明显,但是当它绑定对象规范块时,它仍然不知道 FOO 和 BAR 到底是什么。事实上,FOO 和 BAR 可以访问 'O 对象的唯一方法是因为它们的函数块,当它通过 'MAKE 运行时,绑定到该对象......是的,在它甚至知道它是一个函数之前。那么如果函数定义了自己的局部变量,它会将其主体块重新绑定到那些新的局部变量..因为你猜对了...函数创建自己的内部上下文,它得到相同的 MAKE 处理(但没有内部 SELF单词)。

我希望这有助于以更明显的方式澄清事情。

这是代码不受范围限制的证明:

a: make object! [
    data: "HAHAHAAAAA!!!"
    action: does [print self/data]
]


b: make object! [
    data: "BUMBLING BEHEMOT"
    action: does [print self/data]
]

b/action: get in a 'action

; this will print HAHAHAAAAA!!!
b/action

No Scope!!!?

The reason do "self/bar" cannot know where to find 'BAR is because there is no scope in Rebol (not in the traditional CS meaning at least).

Words in Rebol only have meaning once they have been statically bound to a context. This automagically occurs when you 'MAKE an object, so many people don't even realize it even after years of use.

Here are the steps (loosely) when an object (a.k.a. context) is created.

  • It picks up all the root set words in its spec (in this case [FOO: BAR:] )

  • Adds them to its current internal words (SELF: by default, more if you are using an object as basis)

  • Then binds all the words in the block (hierarchicaly) to those set-words it added to its spec.

  • Executes the block.

So you see, once you execute the block its too late, the words already got assigned their meaning, which allows the interpreter to ask for their values (which could trigger an expression evaluation, hence the E in REBOL).

Global, cause that all there really is once executing.

DO and LOAD cannot automatically bind to anything but the global context... because there is no such thing as the "current context" like you'd have in traditional OOP and imperative languages (remember, no scope). Really, once its executing, that information doesn't exist anymore, unless you bound the "current" context to a word... which is what 'SELF does, but to be bound it has to already be loaded, which, when executing a string, never occured.

clueless functions

I'll finish by adding that it may not be obvious at first sight, but while it was binding the Object spec block, it still didn't know what FOO and BAR really were. in fact, the only way FOO and BAR could access the 'O object, is because their function block, when it was run thru 'MAKE, got bound to the object... yep, before it even knew it was a function. then if the function defined its own locals, it would re-bind its body block to those new locals.. because you guessed it... a function creates its own inner context, which gets the same MAKE treatment (but without the internal SELF word).

I hope this helps clear things in a more obvious light.

here is a proof that code isn't scoped:

a: make object! [
    data: "HAHAHAAAAA!!!"
    action: does [print self/data]
]


b: make object! [
    data: "BUMBLING BEHEMOT"
    action: does [print self/data]
]

b/action: get in a 'action

; this will print HAHAHAAAAA!!!
b/action
奢望 2025-01-10 06:51:26

要更多地解释莫利亚德的答案,请参阅以下解释:

REBOL 单词带有对其上下文的引用。它不是
一个词被评估的地方会产生影响,但是它在哪里
声明。

来自 http://blog.revolucent.net/2009/07/deep- rebol-bindology.html

这是一个很好的例子:

x: 0
b: [] loop 3 [use [x] [x: random 100 append b 'x]]
;== [x x x]   <-- there are three X which looks same words (and they are same actually)

reduce b
;== [95 52 80]  <-- but they have different values in their contexts

probe x
;== 0     <-- in global context, it has another value as well

乍一看这看起来很奇怪,但实际上并非如此。 USE 每次在循环中创建一个新的上下文,我们将 X(在 USE 创建的上下文中)设置为一个值,然后将 WORD(不是值!)附加到一个块中。
我们附加到块中的所有单词都带有自己的上下文,但它们看起来是同一个单词。

当我们减少(或打印等)时,当我们在自己的上下文中获取它们的值时,我们看到它们都有不同的值!

To explain moliad's answer a bit more, see the following explanation:

REBOL words carry a reference to their context with them. It’s not
where a word is evaluated that makes the difference, but where it’s
declared.

from http://blog.revolucent.net/2009/07/deep-rebol-bindology.html

Here is a very good example:

x: 0
b: [] loop 3 [use [x] [x: random 100 append b 'x]]
;== [x x x]   <-- there are three X which looks same words (and they are same actually)

reduce b
;== [95 52 80]  <-- but they have different values in their contexts

probe x
;== 0     <-- in global context, it has another value as well

This looks weird at first look, but actually it is not. USE creates a new context each time in the LOOP, we set X (in the context the USE created) to a value, then APPEND the WORD (not the value!) to a block.
All the words that we append to the block carries their own contexts with them, but they look same word.

When we REDUCE (or PRINT etc.), when we GET their values in their own contexts, we see that they all have different values!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文