Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 1
Регистрация: 22.12.2014
Сообщений: 20

Странная работа скрипта с функциями и возвращаемыми значениями

16.12.2016, 12:26. Показов 3048. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я абсолютный новичок в PowerShell (не считая вызова простейших команд типа управления exchange), но вроде более-менее знаком с 5-6 другими языками программирования и скриптовыми.

Сейчас пробую элементарнейшее создание своей функции и ее вызов, получаю абсолютно абсурдное поведение:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function func
{
echo "func entry "
return 1
}
 
$a=func
echo "echoing a:"
echo $a
echo "trying if: "
if ($a -eq 1)
{
echo "a=1"
}
echo "adding: "
$c=$a+1
echo "echoing c: "
echo $c
Запускаю это дело и получаю вот такой вывод:
PowerShell
1
2
3
4
5
6
7
8
9
10
echoing a:
func entry
1
trying if:
a=1
adding:
echoing c:
func entry
1
1
Получается:
- в момент присваивания $a=func, собственно func не вызывается!
- func вызывается в момент обращения к переменной, которой присвоено возвращаемое значение
- во время сравнения ($a -eq 1) - вызов не происходит, так же, как и во время прибавления $c=$a+1
- при выводе $c опять вызывается func!

Более того, если я закомментирую вызов echo:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function func
{
echo "func entry "
return 1
}
 
$a=func
#echo "echoing a:"
#echo $a
echo "trying if: "
if ($a -eq 1)
{
echo "a=1"
}
echo "adding: "
$c=$a+1
echo "echoing c: "
echo $c
Вывод такой:
PowerShell
1
2
3
4
5
6
7
trying if:
a=1
adding:
echoing c:
func entry
1
1
Получается:
- сначала func просто не отрабатывает, но 1 каким-то непостижимым образом при этом возвращает!
- далее все аналогично, функция отрабатывает именно при выводе $c, которая связана с вызываемой функцией аж через 2 ступеньки. Когда сначала было присвоено $a, потом из $a было по формуле посчитано $c...

Вопрос: что это вообще за издевательство и как с этим всем работать?
Прощу прощения за излишнюю эмоциональность, но вроде, в программировании не первый десяток лет, но с таким поведением языка сталкиваюсь впервые.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.12.2016, 12:26
Ответы с готовыми решениями:

класс с 2 возвращаемыми значениями
необходимо чтобы класс вернул 2 значения: List<int> и переменную string. Как обьявить такой класс и вызвать его?

Можно ли создать метод с несколькими возвращаемыми значениями
На пример: pupblic double,int metod() { } Может писать надо по другому,но смысл я надеюсь вы поняли.Заранее благодарю.

Работа с функциями. Написать программу, которая будет с отрицательными(положительными) значениями вычислять функцию по следующей формуле
Всем привет. Вроде с функциями и процедурами с вашей помощью я разобрался, но тут чуть-чуть иное задание и я не знаю с какой стороны к...

4
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
16.12.2016, 14:24
Немножко беглое объяснение:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function func
{
    #Write-Host "func entry "
    Write-Output "func entry "
    return 1
}
 
 
$a=func
echo "echoing a:"
$a.gettype()
# IsPublic IsSerial Name                                     BaseType                                                                                                                        
# -------- -------- ----                                     --------                                                                                                                        
# True     True     Object[]                                 System.Array     
 
# $a это массив объектов, так как функция в вашем варианте возвращает два значения (упакованных в этот массив объектов)
 
echo $a[0]  # func entry 
echo $a[1]  # 1
# однако если заменить Write-Output\echo  на Write-Host - возвращаться будет одно значение - как вы и ожидали и $c=$a+1  будет равно 2,  так как тип переменной $a будет Int
 
 
echo "echoing a:"
echo $a
echo "trying if: "
if ($a -eq 1)  # на самом деле происходит это: "echoing a:",1 -eq 1   => при сравнении списка со скаляром возвращается совпашее значение либо ничего
{
    echo "a=1"
}
echo "adding: "
#$c=$a[1]+1 # если прибавлять так, то получим ожидаемое 2; 
$c=$a+1 # иначе прибавление скаляра к списку просто возвращает новый  список с добавленным значением
# ("echoing a:",1 + 2).gettype()  # System.Array 
echo "echoing c: "
echo $c
Добавлено через 2 минуты
Цитата Сообщение от iltmpz Посмотреть сообщение
Вопрос: что это вообще за издевательство и как с этим всем работать?
Так что работать с этим вполне можно :-) - просто нужно учитывать нюансы, что это именно командно-ориентированный язык и некоторые вещи могут не совпадать с привычными парадигмами.

Добавлено через 23 минуты
PS: Ваша ошибка в том, что вы не учли разницу между двумя командлетами: Write-Output\echo - предназначен для передачи значения по pipeline (если есть куда передавать, иначе записывает в stdout) и поэтому он возвращает значение, а Write-Host просто записывает значение в stdout и ничего не возвращает.
1
0 / 0 / 1
Регистрация: 22.12.2014
Сообщений: 20
16.12.2016, 16:32  [ТС]
Большое спасибо!
Хороший метод gettype(), приму на вооружение.
Значит, получается, если функция пишет что-то в pipeline, то оно записывается в массив, который при return дополняется последним параметром этого самого return, и этот массив возвращается, так?

В голову не могло придти, что такая подстава окажется с обычнейшей функцией echo, теперь почитал, буду знать.
Сейчас заменил все echo на Write-Host - заработало как надо!

А если я вместо echo буду из своей функции вызывать другие команды/функции? Надо по каждой смотреть, куда она возвращает результат и не будет ли на выходе "сюрприза" в виде массива вместо ожидаемого значения?
Нагуглил, как поместить результаты вывода команды в массив для дальнейшей с ним работы, получилось:
$r=@(Get-MailboxExportRequest)
Вроде, выходной pipeline ничем не забивается, я правильно делаю? Сюрпризов не будет?

А можно еще тут же другой вопрос не по теме? Про обработку ошибок?
Написал: return True (Вместо return "True"), оно ругнулось, что мол, синтаксис неправильный и... продолжило выполнение, нарушив логику скрипта.
Можно как-то поменять механизм обработки ошибок, чтобы оно грохалось в случае таких ошибок? А лучше всего, вообще не запускалось сразу...
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
16.12.2016, 17:47
iltmpz,
Цитата Сообщение от iltmpz Посмотреть сообщение
если функция пишет что-то в pipeline, то оно записывается в массив
Не совсем так. Если значение для передачи в pipeline одно (скаляр\строка), никакого массива сформировано не будет.
Ваш вариант с
PowerShell
1
2
3
4
5
6
function func
{
    Write-Output "func entry "
    return 1
    
}
можно иначе записать как
PowerShell
1
2
3
4
function func
{
   Write-Output "func entry ",1
}
где в явном виде указан список значений и именно он (в качестве последнего значения функции) и будет считаться возвращаемым значением функции. Так как список в данном случае не типизирован, то исходя из внутренней типологии .NET он получит определение как массив объектов - System.Array.
NB: В powershell само использование return необязательно для возврата значений; результат последнего вычисленного выражения и так будет неявным возвращаемым значением функции. Но если таких значений окажется несколько - то возвращаемым результатом станет массив этих значений.

Цитата Сообщение от iltmpz Посмотреть сообщение
Надо по каждой смотреть, куда она возвращает результат и не будет ли на выходе "сюрприза" в виде массива вместо ожидаемого значения?
Проверять тип полученного значения в принципе и так принято в прочих языках программирования, так что и в powershell не помешает. Только изначально его лучше проверить на if ($var -ne $null) или if (!$var) (второй способ, как пишут, надежнее), а потом уже на требуемый тип.

Цитата Сообщение от iltmpz Посмотреть сообщение
Написал: return True (Вместо return "True")
Для явной передачи булевских литералов в powershell используются встроенные переменные $true и и $false. Так что в вашем случае неправильный литерал будет интерпретирован как null.

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

Добавлено через 10 минут
Про возврат значений из пользовательских функции вот здесь более подробно написано.
1
 Аватар для v_svitere
774 / 423 / 137
Регистрация: 03.06.2009
Сообщений: 1,223
Записей в блоге: 4
16.12.2016, 17:55
iltmpz,
А можно еще тут же другой вопрос не по теме? Про обработку ошибок?
Написал: return True (Вместо return "True"), оно ругнулось, что мол, синтаксис неправильный и... продолжило выполнение, нарушив логику скрипта.
Можно как-то поменять механизм обработки ошибок, чтобы оно грохалось в случае таких ошибок? А лучше всего, вообще не запускалось сразу...
Вот тут тоже 2 статейки про обработку ошибок.
http://windowsnotes.ru/powersh... l-chast-1/
http://windowsnotes.ru/powersh... l-chast-2/
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.12.2016, 17:55
Помогаю со студенческими работами здесь

Метод с различными возвращаемыми типами
Доброго времени суток. Нужно создать метод, который возвращает разные типы: public T foo<T>() { return...

Странная работа Wi-Fi
Вчера начал пропадать интернет т.е. есть, рраз на пол минуты - минуту отключается и снова есть, пропадет по разному бывает каждые 5 минут,...

Странная работа ПК
Всем привет. Вчера все было нормально, сегодня начал заходить в игру - начал замечать что при заходе в нее начинает что-то свистеть в...

Странная работа vk.com
Недавно я проапгрейдил комп, поставил новую мать, ссд и проц, и сверху на ссдшник накатил новую винду. Однако после переустановки виндовс...

Странная работа БД
Спасибо всем тем, кто решил откликнуться. Сначала лирика: Имеется проект "Калькулятор", созданы различные типы инженерный,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru