"Обозначение объектов APL" в Dyalog APL
Как преобразовать любое значение Dyalog APL в вектор символов, который может быть передан ⍎
получить такое же значение?
Как это будет выглядеть:
x←2 3⍴⍳6
x←1,⊂x
x←x,⊂'foo'
y←desired_function x
DPX y
┌→─────────────────┐
│1,(⊂2 3⍴⍳6),⊂'foo'│
└──────────────────┘
x≡⍎y
1
Обновить
Идея состоит в том, чтобы преобразовать значение в редактируемый человеком исходный код APL, чтобы иметь возможность вставить его в функцию модульного теста, когда обнаружен новый проблемный сценарий. Я хочу, чтобы эти тестовые сценарии были в исходном коде APL, а не в файлах, потому что в среде, с которой я работаю, исходный код хорошо управляется системой контроля версий, а файлы - нет. И я хочу, чтобы он был редактируемым человеком, а не просто сериализованным, чтобы упростить изменение существующих сценариев тестирования при изменении аргументов / результатов.
5 ответов
⎕SE.Dyalog.Utils.repObj
Например:
x←2 3⍴⍳6
x←1,⊂x
x←x,⊂'foo'
y←⎕SE.Dyalog.Utils.repObj x
]Display y
┌→─────────────────────┐
│1 (2 3⍴1-⎕io-⍳6) 'foo'│
└──────────────────────┘
x≡⍎y
1
На мой взгляд, Execute & "форма перевода" не являются оптимальными решениями по ряду причин:
- Сложные структуры быстро становятся трудными для чтения
- Execute - относительно тяжелый / неэффективный инструмент для вызова, сравнения с другими решениями.
- Если вы неосторожны, вы открываете себя для "инъекционных" атак, вредоносного кода в файлах, которые должны содержать константы, но выполняются при запуске вашего приложения.
В зависимости от того, как выглядят ваши данные, JSON может быть хорошим способом - это формат, разработанный специально для этого:
В Дялог 15.0:
fromJSON←7159⌶ ⋄ toJSON←7160⌶
(namespace←⎕NS '').life←42
toJSON (⍳4) 'Hello' namespace
[[1,2,3,4],"Hello",{"life":42}]
Недостатком JSON является то, что он не может представлять массивы более высокой размерности. Поэтому вам нужно немного помассировать, если вам нужны матрицы:
toJSON ↓3 4⍴⍳12
[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
↑fromJSON '[[1,2,3],[5,6,7]]'
1 2 3
5 6 7
В версии 16.0, которая будет выпущена в конце этого месяца, экспериментальные двутавровые балки стали системной функцией SONJSON.
Не уверен насчет Dyalog APL, но большинство других APL имеют встроенные функции для достижения этой цели.
В IBM APL2 (и, следовательно, также в GNU APL) вы можете использовать 2 ⎕TF для преобразования между значением (фактически переменной с этим значением) и кодом APL, который его генерирует (хотя и не через via, а через еще 2 ⎕TF):
4 ⎕CR x
┏→━━━━━━━━━━━━━━┓
┃1 ┏→━━━━┓ ┏→━━┓┃
┃ ↓1 2 3┃ ┃foo┃┃
┃ ┃4 5 6┃ ┗━━━┛┃
┃ ┗━━━━━┛ ┃
┗∊━━━━━━━━━━━━━━┛
⎕←text←2 ⎕TF 'x'
x←1 (2 3⍴1 2 3 4 5 6) 'foo'
)erase x
2 ⎕TF text
x
4 ⎕CR x
┏→━━━━━━━━━━━━━━┓
┃1 ┏→━━━━┓ ┏→━━┓┃
┃ ↓1 2 3┃ ┃foo┃┃
┃ ┃4 5 6┃ ┗━━━┛┃
┃ ┗━━━━━┛ ┃
┗∊━━━━━━━━━━━━━━┛
В GNU APL вы также можете использовать 10 ⎕CR для этой цели. Результат состоит из нескольких операторов APL, поэтому вам нужно ⍎¨ поверх результата:
10 ⎕CR 'x'
x←1 00 00 ((⎕IO+1)⊃x)←2 3⍴1 2 3 4 5 6 ((⎕IO+2)⊃x)←'foo'
⊃10 ⎕CR 'x'
x←1 00 00
((⎕IO+1)⊃x)←2 3⍴1 2 3 4 5 6
((⎕IO+2)⊃x)←'foo'
Я не знаю, есть ли способ сделать это с ⍎, но я упомяну, что Dyalog версии 15.0 имеет 2 I-Beam для сериализации и десериализации.
http://help.dyalog.com/15.0/Content/Language/Primitive%20Operators/Serialise%20Array.htm
например
]disp x
┌→┬─────┬───┐
│1│0 1 2│foo│
│ │3 4 5↓ │
└─┴~───→┴──→┘
y← 0(220⌶) 0(219⌶) 1(219⌶) 1(220⌶) x
]disp y
┌→┬─────┬───┐
│1│0 1 2│foo│
│ │3 4 5↓ │
└─┴~───→┴──→┘
y ≡ x
1
Кроме того, вы можете присоединиться к нашим форумам, чтобы привлечь больше пользователей Dyalog APL, если бы вы задали здесь свой вопрос.
С Уважением,
Винс
Если я что-то не упустил, интерпретатор не предоставляет механизма для сохранения и перестройки любого возможного типа переменной (есть много сложностей с пространствами имен, объектами, ссылками на любой из них и т. Д.). "Сериализация" может быть ближе всего, но (а) она не читаема человеком, и (б) это скорее механизм интерпретатора, чем инструмент для разработчиков приложений, поэтому я даже не хочу говорить об этом дальше - есть лучшие способы иметь дело с этим;)
Тем не менее, есть пользовательская команда, которая позволит вам сделать это:
]save (Object) (Filename)
так
]save x h:\temp\x
сохранил его в unicode-файл h:\temp\x.dyalog, который также можно редактировать с помощью любого редактора с поддержкой Unicode (или даже редактировать h:\temp\x.dyalog).
При выполнении
]load h:\temp\x
Вы можете загрузить этот объект в рабочую область. В качестве альтернативы используйте
]xyz←load h:\temp\x -noname
присвоить значение xyz
вместо загрузки в x
снова.
И это еще не все... Я предполагаю, что ваш вопрос - результат желания воспроизвести некоторые данные. Знаете ли вы о "файловой системе компонентов", которая предлагает простой способ сохранения переменных, таких как x
к файлам и перезагрузить их оттуда? Пример:
{x ⎕fappend ⍵ ⋄ ⎕FUNTIE ⍵}'h:\temp\x'⎕FCREATE 0
сохранить x
а потом
{r←⎕fread ⍵,1 ⋄ ⎕FUNTIE ⍵ ⋄ r}'h:\temp\x'⎕FTIE 0
чтобы прочитать это снова. (Отказ от ответственности: эти примеры слишком упрощены, потому что нет никакой обработки ошибок в случае, если файл, который вы создаете, уже существует и т. Д. - обычно об этом также нужно заботиться, но это было бы слишком большим отвлечением для этого небольшого образец...)
Итак, наконец, я думаю, что моя настоящая обеспокоенность связана с контекстом этой проблемы и целью, которую вы пытаетесь достичь. За всю свою жизнь в APL я редко видел вещи, которые "не выполнимы", но иногда путь отличается от того, что вы ожидаете (зная другие языки)...