LINUX.ORG.RU

Как получить доступ к локальным переменным в двух функциях?

 


0

1

Только локальные переменные нужны. Никаких глобальных

function f1 () {
   local var1 = some1
   local var2 = some2
}

function f2 () {
    f1  # <-- хотелось бы что-то такое. Типа загрузили f1 и имеем доступ к переменным, чтобы по 10 раз не дублировать var1 и var2 в f1...fx
    echo ${var1}
    echo ${var2}
}

function f3 () {
    f1
    echo ${var1}
    echo ${var2}
}
★★★★

Последнее исправление: bryak (всего исправлений: 4)

Понимаю, что вы спрашиваете совсем не об этом, но не могу молчать: вы где-то в жизни свернули не туда, если вам такое нужно в bash’е. Либо шелл смените на язык программирования, либо попытайтесь решить чего вы там делаете более идиоматичным образом.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

Понимаю, что вы спрашиваете совсем не об этом, но не могу молчать: вы где-то в жизни свернули не туда, если вам такое нужно в bash’е. Либо шелл смените на язык программирования, либо попытайтесь решить чего вы там делаете более идиоматичным образом.

Изначально это всё задумывалось как штука, для запуска которой не надо устанавливать какие-то пакеты. Но потом, когда начал расширять функциональность, чтобы это стало удобным - все «прелести» баш сразу вылезли наружу. Сейчас я бы это сделал на каком-то lua(и горя бы не знал)

bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 2)

по 10 раз не дублировать var1 и var2

Сделать им общее имя (объединить в структуру).

В параметры f1…fx передавать одно это общее имя (и за счёт этого не дублировать при передаче var1 и var2)

«В Bash нет структур данных (struct) в стиле языков C или C++, но существуют механизмы для организации сложных данных: ассоциативные массивы (хэш-таблицы), обычные одномерные массивы, а также переменные, эмулирующие структуры через соглашения об именовании (например, user1_name, user1_id).»

Saakx
()
Последнее исправление: Saakx (всего исправлений: 1)
Ответ на: комментарий от bryak

Bash — не про красоту. Ты хочешь странного, и такой способ решает твою проблему.

А локальные переменные на то и локальные, что к ним не должно быть доступа извне, тем более из другой функции.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от bryak

Резать не дожидаясь перетонита! Но если уж никак, то можно запихнуть разделяемые данные в массив, который передавать через nameref.

#!/usr/bin/env bash

f1() {
    local -n result="$1"
    local var1=some1
    local var2=some2
    result=($var1 $var2)
}

f2() {
    local vars
    f1 vars
    declare -p vars
}

f2

Ничего лучше что-то не придумывается.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

Еще можно так))

function f1 () {
    local SRV_NAME='gpm'
    local SRV_NAME_PKG=(
        gpm
    )

    echo "SRV_NAME=$SRV_NAME"
    echo "SRV_NAME_PKG=(${SRV_NAME_PKG[@]})"
}

function f2 () {
    eval "$(f1)"

    echo "${SRV_NAME_PKG[@]}"
}

f2
bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 1)
Ответ на: комментарий от bryak

Они же локальные. Не позатирают.

Во всех нормальных ЯП локльные переменные явно объявляют и всё прекрасон работает. Не всегда повторяющиеся строки в программе - ошибка, от которой надо избавляться.

legolegs ★★★★★
()

я конечно баш не особо хорошо знаю, но вот возникает чисто технический вопрос

вот в этом случае


function f1 () {
   local var1 = some1
   local var2 = some2
}

function f3 () {
    f1
    echo ${var1}
    echo ${var2}
}

что собственно говоря должна вывести на экран echo? f1 ведь не вызывалась и значения не присвоены, вроде как

anonymous
()

Гм, ты что куришь? То у тебя «строки многострочные» то «нелокальные локальные переменные»… Лучше б ты маны курил, ей богу.

И, кстати, в перле есть то, что ты хочешь. ;-) Я тебе говорил: бери перл…

debugger ★★★★★
()
Ответ на: комментарий от debugger

Гм, ты что куришь? То у тебя «строки многострочные» то «нелокальные локальные переменные»… Лучше б ты маны курил, ей богу.

Ты же видишь, что я делаю так, чтобы было удобно. Пофигу на архитектуру самого баша. Являются какие-то там переменные локальными по отношению к каким-то там функциям архитектурно или нет - главное чтобы мне удобно было

Так поздно брать что-то другое. Да и если переписывать, то на модный луа, а не на перл

bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 1)

Если действительно нужно сделать как требуется, то нужно писать маленькую программку на С, читать указатель стека, брать правильное смещение учитывая эпилог, линк-энд-джамп адрес возврата, неволотайл регистры, и вот они ваши var1, var2 от функции f1. Но как уже справедливо заметили, где-то вы пропустили поворот, раз понадобилось такое дело.

VIT ★★
()
function f1 () {
   local var1 = some1
   local var2 = some2
   echo "${var1}" "${var2}"
}

function f2 () {
#    f1  # <-- хотелось бы что-то такое. Типа загрузили f1 и имеем доступ к переменным, чтобы по 10 раз не дублировать var1 и var2 в f1...fx
    array=($( f1 ))
    local var1 = "${array[0]}"
    local var2 = "${array[1]}"
    echo ${var1}
    echo ${var2}
}

Не проверял

А, можно как Aceler писал, через параметры. Что-то типа: f2 $( f1 ) , при вызове, а внутри использовать «${1}» «${2}».

sin_a ★★★★★
()
Последнее исправление: sin_a (всего исправлений: 1)
Ответ на: комментарий от sin_a

А потом ты скажешь что переменные с пробелами, а я тебе скажу перебирать их в цикле, а ты скажешь что они в несколько строк а я скажу про жейсон, и короче придём к тому что он сказал – к временному файлу. К набору временных файлов…

sin_a ★★★★★
()
Последнее исправление: sin_a (всего исправлений: 1)
Ответ на: комментарий от LongLiveUbuntu

Ему тогда придётся с export колдовать. Если смотреть на bash как на CLI/as framework, то немножко проще жить: не примерять на него традиционные подходы ЯП.

anonymous
()
Ответ на: комментарий от bryak

Ты же видишь, что я делаю так, чтобы было удобно.

Я вижу, что ты всё делаешь через ж… Альпы.

Пофигу на архитектуру самого баша.

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

Да и если переписывать, то на модный луа, а не на перл

Дело, конечно, хозяйское, но ты же сам заявлял, что всё равно, лишь бы в поставке было. Перл есть в поставке, а луа — хоть и модный, но недоязык: регулярки в луа убогие, структуры данных, вернее структура — тоже ни рыба, ни мясо, а какая-то ублюдочная помесь массива с хешем. Какой смысл переходить с одного недоязыка на другой?

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 1)
Ответ на: комментарий от kaldeon

Прям вот совсем так нельзя, но в кложе, например, есть destructing поэтому можно так:

user> (defn f1 []
  (let [var1 "some1"
        var2 "some2"]
    [var1 var2]))
#'user/f1
user> (f1)
["some1" "some2"]
user> (defn f2 []
  (let [[var1 var2] (f1)]
    (println var1 var2)))
#'user/f2
user> (f2)
some1 some2
nil

ugoday ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

Тогда уж Питон: в поставке почти 100% есть, читаемость хорошая, библиотека богатая.

Если не вдаваться в тонкости и вкусовщину, то у перла перед питоном есть преимущество: перл пригоден для написания однострочников и может заменить всякие седы, грепы, авки, таки, ревы и множество других утилит, а питон — нет.

debugger ★★★★★
()

Правильно будет сделать переменные локальными относительно скрипта. Чуть более костыльный метод — выдавать каждой локальной переменной — по функции и получать их содержимое внутри другой функции, где это нужно.

Если бы это был какой-нибудь Python, можно было бы делать всякие foo, bar = get_foobar(), но ты пошёл по граблям, так что наслаждайся болью. (=

mord0d ★★★★★
()

В общем случае копий локальных переменных может быть несколько, если ф-ция вызывается несколько раз вложено, так что постановка вопроса некорректная.

Займитесь рефакторингом.

Psilocybe ★★★★★
()