PowerShell - Механизм замены части данных в Powershell

Аватара пользователя
DJ Mogarych

PowerShell - Механизм замены части данных в Powershell

Сообщение DJ Mogarych »

Уважаемые товарищи, объясните мне, пожалуйста, одну вещь.



Вот есть какие-то данные, к примеру, список процессов, я их помещаю в переменную:



Код:

Код: Выделить всё

$src = get-process |select name,product,ProductVersion |? product -match "операционная система"
Результат:
Name           Product                                  ProductVersion
----           -------                                  --------------
explorer       Операционная система Microsoft® Windows® 10.0.17763.769
smartscreen    Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
SystemSettings Операционная система Microsoft® Windows® 10.0.17763.769
taskhostw      Операционная система Microsoft® Windows® 10.0.17763.769

Дальше я беру и создаю переменную из куска предыдущих данных:



Код:

Код: Выделить всё

$piece = $src |? name -match smart
Результат:
Name        Product                                  ProductVersion
----        -------                                  --------------
smartscreen Операционная система Microsoft® Windows® 10.0.17763.769

Теперь я беру и меняю имя в этом куске:



Код:

Код: Выделить всё

$piece.name = "Умный экран"
Результат:
Name        Product                                  ProductVersion
----        -------                                  --------------
Умный экран Операционная система Microsoft® Windows® 10.0.17763.769

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



Код:

Код: Выделить всё

$src
Результат:
Name           Product                                  ProductVersion
----           -------                                  --------------
explorer       Операционная система Microsoft® Windows® 10.0.17763.769
Умный экран    Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
svchost        Операционная система Microsoft® Windows® 10.0.17763.769
SystemSettings Операционная система Microsoft® Windows® 10.0.17763.769
taskhostw      Операционная система Microsoft® Windows® 10.0.17763.769

Это очень удобно - можно, к примеру, менять загруженный в память CSV построчно по определённой выборке, но я не понимаю, почему, изменяя один объект, по идее, являющийся отдельным, меняется другой.



Кто-нибудь знаком с этим механизмом?
Аватара пользователя
YuS_2

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение YuS_2 »

Цитата DJ Mogarych:



не понимаю, почему, изменяя один объект, по идее, являющийся отдельным, меняется другой.
PowerShell - Механизм замены части данных в Powershell




В powershell, массивы создаваемые оператором присваивания, работают по ссылке на один и тот же объект.

Изменение размера массива, фактически создает новый массив и в этом случае, они уже не будут взаимосвязанными.

Для иллюстрации:



Код:

Код: Выделить всё

$a=,1
$b=$a
$b[0]=3
$a
$b+=1
$b[0]=10
$a
Аватара пользователя
Iska

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение Iska »

DJ Mogarych, как верно сказал коллега YuS_2, это поведение зависит от того, что происходит в конкретном языке при реализации операции присваивания объектных переменных в том или ином случае. В приведённом Вами случае, надо полагать, что некоей переменной X, стоящей слева от оператора присваивания, присваивается ссылка на ту же самую коллекцию объектов (в памяти), на которую ссылается некая переменная Y, которая находится справа от оператора присваивания. Где-то этим поведением можно управлять явно, где-то — неявно, а где-то — управлять вовсе нельзя (как было задано создателями языка, так, мол, и пользуйте).
Аватара пользователя
DJ Mogarych

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение DJ Mogarych »

Получается, что без изменения размеров область памяти одна, и переменные работают как фильтр, а если изменить размер, системе приходится создавать новый объект?
Аватара пользователя
Busla

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение Busla »

Цитата YuS_2:



Изменение размера массива, фактически создает новый массив
PowerShell - Механизм замены части данных в Powershell




в PowerShell массивы фиксированного размера, поэтому никакого изменения размера массива попросту нет. Операция массив + что-то возвращает новый массив.




Цитата DJ Mogarych:



если изменить размер, системе приходится создавать новый объект
PowerShell - Механизм замены части данных в Powershell




система никаких решений не принимает, набор операция для каждого типа определён заранее



К сожалению, что и как реализовано можно только выучить.
Аватара пользователя
YuS_2

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение YuS_2 »

Цитата Busla:



Операция массив + что-то возвращает новый массив.
PowerShell - Механизм замены части данных в Powershell




Уважаемый, вы если решили поумничать на пустом месте, то вчитайтесь в то, что написано выше, а именно в то, что вы процитировали...

Что вы хотели сказать - непонятно, ибо написали то же самое, что написано в цитате, просто другими словами... нет?
Аватара пользователя
Busla

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение Busla »

Цитата YuS_2:



написали то же самое, что написано в цитате, просто другими словами... нет?
PowerShell - Механизм замены части данных в Powershell




нет

я описал реализацию, а вы - магию

очень показательно, как ваше "то же самое" воспринял топикстартер:


Цитата DJ Mogarych:



Получается, что без изменения размеров область памяти одна, и переменные работают как фильтр, а если изменить размер, системе приходится создавать новый объект?
PowerShell - Механизм замены части данных в Powershell




размер тут не при чём

для списков определена операция добавления:



Код:

Код: Выделить всё

> $a = New-Object 'System.Collections.Generic.List[int]'
> $a.Add(4)
> $b=$a
> $a.Add(4)
> $b
4
4

и изменение размера ни к каким пересозданиям не приводит
Аватара пользователя
DJ Mogarych

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение DJ Mogarych »

Цитата Busla:



Операция массив + что-то возвращает новый массив.
PowerShell - Механизм замены части данных в Powershell




Тогда как объяснить ситуацию, описанную мной в самом начале?
Аватара пользователя
YuS_2

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение YuS_2 »

Цитата Busla:



я описал реализацию
PowerShell - Механизм замены части данных в Powershell




Да что вы говорите?! Отлично!

Самомнение у вас раздуто сильно.

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


Цитата Busla:



Операция массив + что-то возвращает новый массив.
PowerShell - Механизм замены части данных в Powershell




Такое описание даже на сказку не тянет, не то что на магию, если что...

Что это за операция такая "Плюс что-то"? Изображение




Цитата Busla:



для списков определена операция добавления:
PowerShell - Механизм замены части данных в Powershell




При чем тут списки вообще? Вы только себя читаете, а вопросы по диагонали?

Там самый обычный массив:


Цитата DJ Mogarych:



$src = get-process |select name,product,ProductVersion
PowerShell - Механизм замены части данных в Powershell






Код:

Код: Выделить всё

PS_5.1> $src = get-process |select name,product,ProductVersion
PS_5.1> $src.gettype()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Попробуйте проделать то же самое с объектом System.Array, т.е.:



Код:

Код: Выделить всё

$a = ,1
$a.add(4)

- что получите в результате?



А потом проверьте:



Код:

Код: Выделить всё

$a.length
$a+=8
$a.length

- для конечного пользователя, это суть "изменение" размера массива, хоть и внутри это работает по-другому, о чем и было сказано.

Вы же полезли на какой-то рожон и решили поумничать.

Бог вам судья, пишите ещё...
Аватара пользователя
Busla

Re: PowerShell - Механизм замены части данных в Powershell

Сообщение Busla »

Цитата YuS_2:



При чем тут списки вообще? Вы только себя читаете, а вопросы по диагонали?
PowerShell - Механизм замены части данных в Powershell




как раз наоборот: вы что-то сказали, а не можете принять, что ваши слова кто-то интерпретирует иначе

и самомнение раздуто у вас

помимо вас тут есть ещё люди, и они тоже что-то пишут



списки это пример того, что вывод из ваших слов получился неверный:


Цитата DJ Mogarych:



переменные работают как фильтр, а если изменить размер, системе приходится создавать новый объект
PowerShell - Механизм замены части данных в Powershell





Цитата DJ Mogarych:



как объяснить ситуацию, описанную мной в самом начале?
PowerShell - Механизм замены части данных в Powershell




Нагляднее всего это проявляется в языках более низкого уровня с прямым управлением памятью: Си, Паскаль - там типы значений и ссылочные типы (указатели) имеют разный синтаксис.




Цитата DJ Mogarych:



список процессов, я их помещаю в переменную
PowerShell - Механизм замены части данных в Powershell




на самом деле это список ссылок на объекты процессов, а в переменной не список, а ссылка на него

Операции над списком ссылок сами объекты процессов не затрагивают, точно так же как и изменение отдельного свойства объекта не копирует и не замещает весь объект. Ссылка на него остаётся той же.
Ответить

Вернуться в «Скриптовые языки администрирования Windows»