Самый простой lmap, как вернуть значение

Это работает нормально:

> lmap x {a b c} {string trim cmd.$x}
cmd.a cmd.b cmd.c

> lmap x {a b c} {list cmd.$x}
cmd.a cmd.b cmd.c

В обоих случаях string trim и list несколько бесполезны. Под бесполезностью я подразумеваю, что они ничего не изменяют и не добавляют к результату. Есть ли способ лучше?

Я попробовал это, но они не дали желаемого результата:

> lmap x {a b c} {return cmd.$x}
cmd.a

> lmap x {a b c} {return -code return cmd.$x}
cmd.a

> lmap x {a b c} {return -code continue cmd.$x}
cmd.a

Что произойдет, если вы используете lmap x {a b c} {cmd.$x}?

mkrieger1 05.05.2024 21:08

Возвращает invalid command name "cmd.a"

thomas 05.05.2024 21:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не понимаю, почему вы воздерживаетесь от использования string trim, в любом случае вы можете использовать lrange

 set your_list {a b c}
 puts [lmap x $your_list {list [lrange cmd.$x 0 end]}]

потому что [string Trim] и [lrange] в моем случае бесполезны

thomas 05.05.2024 20:20

когда вы говорите «бесполезно», у вас проблемы с типом возвращаемого значения? что это такое ?

flash 05.05.2024 20:27

Я не могу последовать за тобой. Под «бесполезным» я подразумеваю, что они не добавляют/изменяют результат... даже ваш пример с lrange не изменяет результат - так зачем же использовать lrange?

thomas 05.05.2024 21:19

я вижу тот же результат с puts [lmap x $your_list {list [lrange cmd.$x 0 end]}]puts [lmap x {a b c} {return -level 0 cmd.$x}] чего мне здесь не хватает?

flash 06.05.2024 06:36
Ответ принят как подходящий

Именно по этой причине был добавлен string cat (cat для конкатенации, по аналогии с командой Unix cat и функцией C strcat()). Как вы заметили, выполняемая им операция является базовой для языка Tcl, но использование ее в качестве команды упрощает lmap.

lmap x {a b c} {string cat cmd.$x}

Этот lmap основной скрипт компилируется в максимально эффективный байт-код.

До того, как был добавлен string cat, официальным способом был return -level 0 cmd.$a, что в конечном итоге было тем же самым, но на самом деле это не мнемоника! В бета-версиях 8.6 он оказался совершенно громоздким, поэтому string cat было сделано быстро, и бета-тестеры ликовали.


Чтобы расширить то, что я имею в виду:

% tcl::unsupported::disassemble lambda {{} {
    lmap x {a b c} {string cat cmd.$x}
}}
ByteCode 0x1ee2cfafbe0, refCt 1, epoch 19, interp 0x1ee2b47a820 (epoch 19)
  Source "lmap x {a b c} {string cat cmd.$x}"
  Cmds 2, src 34, inst 22, litObjs 2, aux 1, stkDepth 6, code/src 0.00
  Proc 0x1ee2cfc5630, refCt 1, args 0, compiled locals 1
      slot 0, scalar, "x"
  Exception ranges 1, depth 1:
      0: level 0, loop, pc 12-17, continue 19, break 20
  Commands 2:
      1: pc 0-20, src 0-33        2: pc 12-17, src 16-32
  Command 1: "lmap x {a b c} {string cat cmd.$x}"
    (0) list 0
    (5) push1 0         # "a b c"
    (7) foreach_start 0
                [jumpOffset=-7, vars=[%v0]]
  Command 2: "string cat cmd.$x..."
    (12) push1 1        # "cmd."
    (14) loadScalar1 %v0        # var "x"
    (16) strcat 2
    (18) lmap_collect
    (19) foreach_step
    (20) foreach_end
    (21) done

% tcl::unsupported::disassemble lambda {{} {
    lmap x {a b c} {expr {"cmd.$x"}}
}}
ByteCode 0x1ee2cfafde0, refCt 1, epoch 19, interp 0x1ee2b47a820 (epoch 19)
  Source "lmap x {a b c} {expr {\"cmd.$x\"..."
  Cmds 2, src 32, inst 23, litObjs 2, aux 1, stkDepth 6, code/src 0.00
  Proc 0x1ee2cfc6430, refCt 1, args 0, compiled locals 1
      slot 0, scalar, "x"
  Exception ranges 1, depth 1:
      0: level 0, loop, pc 12-18, continue 20, break 21
  Commands 2:
      1: pc 0-21, src 0-31        2: pc 12-18, src 16-30
  Command 1: "lmap x {a b c} {expr {\"cmd.$x\"..."
    (0) list 0
    (5) push1 0         # "a b c"
    (7) foreach_start 0
                [jumpOffset=-8, vars=[%v0]]
  Command 2: "expr {\"cmd.$x\"..."
    (12) push1 1        # "cmd."
    (14) loadScalar1 %v0        # var "x"
    (16) strcat 2
    (18) tryCvtToNumeric
    (19) lmap_collect
    (20) foreach_step
    (21) foreach_end
    (22) done

% tcl::unsupported::disassemble lambda {{} {
    lmap x {a b c} {return -level 0 cmd.$x}
}}
ByteCode 0x1ee2cfb01e0, refCt 1, epoch 19, interp 0x1ee2b47a820 (epoch 19)
  Source "lmap x {a b c} {return -level 0 cmd.$x}"
  Cmds 2, src 39, inst 22, litObjs 2, aux 1, stkDepth 6, code/src 0.00
  Proc 0x1ee2cfc68b0, refCt 1, args 0, compiled locals 1
      slot 0, scalar, "x"
  Exception ranges 1, depth 1:
      0: level 0, loop, pc 12-17, continue 19, break 20
  Commands 2:
      1: pc 0-20, src 0-38        2: pc 12-17, src 16-37
  Command 1: "lmap x {a b c} {return -level 0 cmd.$x}"
    (0) list 0
    (5) push1 0         # "a b c"
    (7) foreach_start 0
                [jumpOffset=-7, vars=[%v0]]
  Command 2: "return -level 0 cmd.$x..."
    (12) push1 1        # "cmd."
    (14) loadScalar1 %v0        # var "x"
    (16) strcat 2
    (18) lmap_collect
    (19) foreach_step
    (20) foreach_end
    (21) done

Как видите, байт-код с string cat и return -level 0 один и тот же, а с expr {"..."} есть дополнительный код операции (и, следовательно, смещение перехода отличается для его размещения).

Абсолютно все, что связано с использованием нулевого уровня для таких вещей, как возврат, повышение уровня и повышение уровня, вызывает некоторое удивление. Есть подозрение, что некоторые из них оказались там потому, что это было проще, чем предотвратить их...

Donal Fellows 05.05.2024 22:50

я вижу тот же результат с puts [lmap x $your_list {list [lrange cmd.$x 0 end]}]puts [lmap x {a b c} {return -level 0 cmd.$x}] чего мне здесь не хватает?

flash 06.05.2024 07:53

Поместите свою версию и версию Donals lmap в процедуру, например. proc d {} {lmap x {a b c} {string cat cmd.$x}} и позвоните tcl::unsupported::disassemble proc d и вы увидите, что в вашей версии намного больше шагов.

thomas 06.05.2024 08:56

Вы также могли бы использовать expr "cmd.$x" в теле. Коротко, но не так эффективно; выполняется дополнительный шаг, чтобы попытаться преобразовать результат в число (компилятор expr недостаточно умен, чтобы опустить здесь этот код операции).

Donal Fellows 06.05.2024 10:30

Я пробовал это раньше, но получил invalid bareword "cmd"

thomas 06.05.2024 11:35

Упс, так и должно было быть expr {"cmd.$x"}. Это немного нелепая последовательность персонажей...

Donal Fellows 07.05.2024 20:40

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