Это объяснение объединяет то, что, как мне кажется, Брэд ++ и Джонатан ++ только что научили меня, с тем, что, как я думал, я уже знал, с тем, что я обнаружил, когда копал дальше.
(Моя первоначальная цель состояла в том, чтобы напрямую объяснить таинственное сообщение Брэда No such method '!cursor_start'
. Я пока что потерпел неудачу и вместо этого только что подал отчет об ошибке , но вот что еще я закончил.)
Методы предназначены для естественной работы в классах. Действительно, объявление метода без объявления области действия предполагает has
- и объявление has
принадлежит внутри класса:
method bar {} # Useless declaration of a has-scoped method in mainline
Но на самом деле методы также работают нормально, так как:
sub
с (то есть не ведет себя как объектно-ориентированный метод вообще); или
методы для программирования на основе прототипов (т.е. ориентация объекта, но без классов).
Что действительно делает методы методами, так это то, что они являются подпрограммами с «инвокантом» . Инвокант - это первый параметр специального состояния, который:
Mu
: class foo { my method bar {} .signature .say } # (foo: *%_)
my method bar {} .signature .say # (Mu: *%_)
my method bar {}
bar # Too few positionals passed; expected 1 argument but got 0
self
. Таким образом: my method bar { say self }
bar 42 # 42
:
). Таким образом: my method bar (Int \baz:) { say baz }
say &bar.signature; # (Int \baz: *%_)
bar 42; # 42
bar 'string'; # Type check failed in binding to parameter 'baz'
Сосредоточив внимание только на перспективе инвоканта, регулярные выражения являются методами, которые принимают / ожидают объект соответствия в качестве своего инвоканта.
Регулярное выражение обычно вызывается в трех несколько разных сценариях:
Прямым использованием. Например, my regex foo { . }; say 'a' ~~ &foo; # 「a」
(или просто say 'a' ~~ / . /; # 「a」
, но я расскажу только по существу идентичный именованный пример, чтобы упростить мое объяснение). Это переводится как say &foo.ACCEPTS: 'a'
. Это, в свою очередь, реализовано этим кодом в Rakudo . Как видите, это вызывает регулярное выражение foo
с инвокантом Match.'!cursor_init'(...)
- , которое выполняет этот код без :build
. В результате этого foo
получает новый объект Match
в качестве инвоканта.
Посредством метода .parse
класса Grammar
. Метод .parse
создает новый экземпляр грамматики и затем вызывает верхнее «правило» (rule
/ token
/ regex
/ method
) для этого нового объекта грамматики. Обратите внимание, что Grammar
является подклассом Match
; поэтому, как и в первом сценарии, правилу / регулярному выражению передается пока еще пустой объект соответствия. Если верхнее правило соответствует, новый объект грамматики / соответствия будет возвращен вызовом .parse
. (В противном случае он вернет Nil
.)
Одним из перечисленных выше способов. Верхнее правило в грамматике обычно будет содержать вызовы правил / токенов / регулярных выражений / методов более низкого уровня. Аналогично, автономное правило / регулярное выражение может содержать обращения к другим правилам / регулярным выражениям. Каждый такой вызов будет включать создание другого нового объекта грамматики / соответствия, который становится инвокантом для вложенного вызова. Если вложенный вызов совпадает, и это вызов захвата, то новый объект грамматики / сопоставления добавляется в объект грамматики / сопоставления более высокого уровня.
Вот руководство о том, как это сделать:
http://www.youcanlearnseries.com/Programming%20Tips/CSharp/LDAPReader.aspx
Думаю, ADSI - это лучший вариант. Это довольно просто. Я не вижу более легкого пути. Вы просто запрашиваете LDAP: //
и получаете свойство отличительного имени.