Это ошибка в Control [] при сочетании с InputField []? - PullRequest
2 голосов
/ 07 февраля 2011

Чтобы вам не приходилось читать все нижеприведенное, суть вопроса заключалась в том, что при использовании пользовательских элементов управления в Control или Manipulate необходимо использовать чистые функции . Как указал WReach, это скрыто в документации Manipulate в конце Scope, Controls .

Таким образом, определение такой функции, как inField[x_Dynamic] ниже, возможно, если она передана в Control[] как чистая функция inField[##]&.

Запутывающим аспектом этого вопроса было то, что мой inField был настроенным InputField. И, как указал joebolte, InputField является резервной позицией по умолчанию Control, если ей дана бессмысленная функция. Это делает это без какого-либо предупреждения, что делает отладку немного хитрой.


Первоначальный вопрос (слегка изменен с учетом первого пункта WReach)

Давайте определим кастом InputField[]

inField[Dynamic[x_]] := InputField[Dynamic[x], Expression, FieldSize -> 5]

Затем используйте его в Manipulate[] команде

Manipulate[Table[{h, i, j, k}^n, {n, 1, 5}] // TableForm,
 {{h, 1, "hhh"}, inField},
 {{i, 1, "iii"}, inField[#] &},
 {{j, 2, "jjj"}, InputField[#, Expression, FieldSize -> 5] &}, 
 {{k, 3, "kkk"}, InputField[#, Expression, FieldSize -> 20] &},
 ControlPlacement -> Left]

Manipulate

Обратите внимание, что эта проблема не возникает, когда inField[] вызывается сам по себе inFields

, но используется при использовании Control[] (что подразумевается в конструкции Manipulate) Controls

Мой вопрос: почему Control er * inField отличается от inField[#]&? Есть ли основная причина или это ошибка? Такое поведение встречается в Mathematica 7 и 8.


Редактировать: Мой мотив для выбора пользовательского inField заключается в том, чтобы отлавливать и исправлять пользовательские вводы - больше, чем просто проверка, которую обеспечивает InputField. Э.Г.

inFieldRat[Dynamic[var_]] := Dynamic[If[TrueQ[Element[N[var] // Chop, Reals]], 
       var = Rationalize[var, .05], var = Null, var = Null]; 
       InputField[Dynamic[var], Expression, FieldSize -> 5]]

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011

Попробуйте изменить определение inField следующим образом:

Clear@inField
inField[x_Dynamic] := InputField[x, Expression, FieldSize -> 5]

Изначальное определение убирало обертку Dynamic из аргумента, в результате чего она была немедленно оценена и после этого оставалась постоянной.

Я подозреваю, что наблюдаемые различия в поведении связаны с нестандартной оценкой в ​​Control (что составляет HoldFirst).

Ответ на @ Комментарий Саймона

Мое недопонимание: я решал проблему, когда элемент управления не обновлял свое значение правильно, а не визуальное несоответствие.

В документации на Manipulate говорится, что функция должна быть чистой функцией (под Scope , Controls ).Документация для Control ничего не говорит по этому поводу, но, вероятно, она такая же, поскольку Manipulate построен на Control.Control[{h, inField}] не является действительной формой.Тем не менее, Mathematica не выдает сообщение об ошибке в этом случае.Скорее, он просто полностью игнорирует inField и действует так, как если бы был указан Control[{h}].Я бы назвал это ошибкой.

Я подозреваю, что Control требует чистой функции, потому что символ имеет неоднозначное значение.Должен ли он использовать отрицательные значения или собственные значения символа (или даже повышающие значения)?WRI, видимо, пошел за ответом own-values.Я все еще думаю, что сообщение оправдано, если выражение оценивает что-то, что не понято Control.

1 голос
/ 08 февраля 2011

Ваш пример несколько сбит с толку, потому что InputField - это то, что Control возвращает, когда домен ничего не оценивает. Рассмотрим Control[{h, z}] (где z не определено) как еще более поразительную версию примера Велизария.

inField2 = Function[{x}, InputField[x, Expression, FieldSize -> 5]]

работает правильно, хотя, если вы просто хотите установить размер поля ввода, я рекомендую

Manipulate[x, {{x, 5, "x"}, InputField, FieldSize -> 5} ]

Edit: если вы хотите, чтобы Manipulate мог динамически сбрасывать свои собственные переменные, как указывает ваше редактирование, я рекомендую что-то вроде

Manipulate[ If[x < 5, x = 5]; x, {x, 0, 10, InputField} ]

1 голос
/ 07 февраля 2011

Просто наблюдение

Control и Manipulate маскируют все, что происходит внутри InputField, включая синтаксические ошибки.

Попробуйте эту бессмысленную конструкцию:

Control[{h, InputField[1, 1, 1, 1, pp -> 1, , FieldSize -> MyError]}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...