Как расширить объект, добавив функцию, а затем получить доступ к исходному объекту, используя self?

Я определяю простой объект с двумя полями. Позже я хочу расширить его с помощью функции, которая может читать эти поля. (На данный момент, скажем, он просто хочет распечатать один из них.)

email-service!: context [ 
    key: "abcd" 
    secret: "" 
] 

extend email-service! 'get-folders does [print self/key]

my_email: make email-service! [
    key: "asdfasdf" 
    secret: "who knows?" 
] 

my_email/get-folders 

Ожидаемый результат - asdfasdf, но вместо этого ничего не распечатывается.

В качестве небольшого поворота замените "дел" на функцию:

extend email-service! 'get-folders func [] [print self/key]

1 ответ

Решение

Учитывая работу "определения объема"... ваша рутина определяется как does [print self/key] сделал связывание в окружающем контексте. Этот контекст может быть модулем или некоторым контекстом, который мы здесь не видим.

Но давайте введем ручной контекст, чтобы показать, что я имею в виду:

context [
    key: "OUTER CONTEXT KEY"

    email-service!: context [ 
       key: "abcd" 
       secret: "" 
    ] 

    extend email-service! 'get-folders does [print self/key]

    my_email: make email-service! [
        key: "asdfasdf" 
        secret: "who knows?" 
    ] 

    my_email/get-folders 
]

Это даст вам "КЛЮЧ ОТ НАРУЖНОГО КОНТЕКСТА" в качестве вывода. Эта функция, которую вы определяете, знает только о включающем ее контексте, она не знает, что позже вы будете передавать ее по параметру, чтобы стать новым членом email-service!,

Но, очевидно, ваш вопрос не о том, как поместить функцию в определение email-сервиса! Вы хотите добавить это после факта. Как подключить его, чтобы узнать о email-сервисе? Путем явного связывания тела функции там, где вы хотите.

email-service!: context [ 
    key: "abcd" 
    secret: "" 
] 

extend email-service! 'get-folders does bind [print key] email-service!

my_email: make email-service! [
    key: "asdfasdf" 
    secret: "who knows?" 
] 

my_email/get-folders 

Это должно дать вам желаемый "asdfasdf". Если бы вы хотели сделать это с помощью функции, вы бы сделали то же самое... связать тело:

extend email-service! 'get-folders func [] bind [print key] email-service!

Вам решать, стоит ли связывать свое слово с email-сервисом! и использовать это. Вам здесь не нужно (обратите внимание, что я говорю print key и не print self/key ) Просто помните, что каждое слово, с которым вы имеете дело, может иметь привязку для оценки... и оно может отличаться даже для слов с одинаковым написанием в коде, составленном из нескольких контекстов.

Другие вопросы по тегам