2017-01-30 91 views
0

Я работаю над сценарием AWK, который довольно большой беспорядок на данный момент, и я пытаюсь его улучшить (в первую очередь потому, что я хочу улучшить свои навыки написания скриптов Awk)Функция AWK Curry - Может ли функция вернуть функцию?

Я понимаю, что нет способ сделать объектно-ориентированное программирование в Awk или Gawk, но есть ли способ, по крайней мере, карри-функции? Как при возврате функции из функции? (Не возвращает результат выполняемой функции, а возвращает функцию, которая может быть выполнена)

Я нашел Stack Overflow post, где @GreenFox показал, что его можно выполнить функцию с именем функции, хранящегося в Переменная. Пример, который он опубликовал, приведен ниже:

function foo(s){print "Called foo "s} 
function bar(s){print "Called bar "s} 
{ 
    var = ""; 
    if(today_i_feel_like_calling_foo){ 
     var = "foo"; 
    }else{ 
     var = "bar"; 
    } 
    @var("arg"); # This calls function foo(), or function bar() with "arg" 
} 

Что мне интересно, возможно ли вернуть функцию из другой функции.

Например, функция, которая принимает строку, которая может использоваться в awks printf в качестве формата, и возвращает функцию, которая принимает два других аргумента и по существу выполняет printf(fmt_from_parent_func, sub_func_arg1, sub_func_arg2).

Вот моя попытка пытается выполнить следующие действия:

#! /usr/local/bin/awk -f 

function setFmt (fmt){ 
    function _print (var, val){ 
    printf (fmt ? fmt : "%-15s: %s\n"), str1, str2 
    } 
    return @_print 
} 
BEGIN { 
    fmtA = setFmt("%-5s: %s\n") 
    @fmtA("ONE","TWO") 
} 

что приводит к ошибкам:

awk: ./curry.awk:4: function _print (var, val){ 
awk: ./curry.awk:4: ^syntax error 
awk: ./curry.awk:4: function _print (var, val){ 
awk: ./curry.awk:4:        ^syntax error 
awk: ./curry.awk:6:  printf (fmt ? fmt : "%-15s: %s\n"), str1, str2 
awk: ./curry.awk:6:             ^unexpected newline or end of string 
awk: ./curry.awk:11: fmtA = setFmt("%-5s: %s\n") 
awk: ./curry.awk:11:       ^unexpected newline or end of string 
awk: ./curry.awk:12: @fmtA("ONE","TWO") 
awk: ./curry.awk:12:     ^unexpected newline or end of string 

Если кто-нибудь знает, если это вообще возможно (что Im начиная видеть себя), и знает способ сделать что-то с этой целью .. это было бы потрясающе.

Спасибо!

ответ

2

С GNU awk вы можете вернуть имя функции в виде строки из другой функции, но вы не можете объявить функцию внутри другой функции и не можете вернуть функцию (или массив) в любом awk - все, что вы можете возврат из функции в awk является скалярным значением (т. е. числом или строкой).

Это то, что вы пытаетесь сделать:

$ cat tst.awk 
function _print (var, val){ 
    printf _print_fmt, var, val 
} 

function setFmt (fmt){ 
    _print_fmt = (fmt ? fmt : "%-15s: %s\n") 
    return "_print" 
} 

BEGIN { 
    fmtA = setFmt("%-5s: %s\n") 
    @fmtA("ONE","TWO") 
} 

$ awk -f tst.awk 
ONE : TWO 
+0

Не совсем. Похоже, что нет возможности выполнить это, поскольку функции Awk не являются работоспособными. – Justin

+0

Можете ли вы подробно остановиться на «не совсем»? Что должен сделать код, который я написал, чтобы этого не делать? Если это не так, если вы можете показать нам, что вы пытаетесь сделать (в отличие от того, как вы это пытаетесь), с кратким, проверяемым образцом ввода и ожидаемым выходом, то я уверен, что кто-то может помочь вам сделать все, что угодно вы пытаетесь сделать идиоматически в awk. –