Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Механизм замены части данных в Powershell (http://forum.oszone.net/showthread.php?t=342277)

DJ Mogarych 20-09-2019 21:49 2888870

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

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

$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 20-09-2019 22:49 2888874

Цитата:

Цитата DJ Mogarych
не понимаю, почему, изменяя один объект, по идее, являющийся отдельным, меняется другой. »

В powershell, массивы создаваемые оператором присваивания, работают по ссылке на один и тот же объект.
Изменение размера массива, фактически создает новый массив и в этом случае, они уже не будут взаимосвязанными.
Для иллюстрации:
Код:

$a=,1
$b=$a
$b[0]=3
$a
$b+=1
$b[0]=10
$a


Iska 20-09-2019 23:30 2888876

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

DJ Mogarych 21-09-2019 07:45 2888905

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

Busla 21-09-2019 10:42 2888924

Цитата:

Цитата YuS_2
Изменение размера массива, фактически создает новый массив »

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

Цитата:

Цитата DJ Mogarych
если изменить размер, системе приходится создавать новый объект »

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

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

YuS_2 21-09-2019 12:28 2888930

Цитата:

Цитата Busla
Операция массив + что-то возвращает новый массив. »

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

Busla 21-09-2019 13:42 2888942

Цитата:

Цитата YuS_2
написали то же самое, что написано в цитате, просто другими словами... нет? »

нет
я описал реализацию, а вы - магию
очень показательно, как ваше "то же самое" воспринял топикстартер:
Цитата:

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

размер тут не при чём
для списков определена операция добавления:
Код:

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

и изменение размера ни к каким пересозданиям не приводит

DJ Mogarych 21-09-2019 14:54 2888957

Цитата:

Цитата Busla
Операция массив + что-то возвращает новый массив. »

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

YuS_2 21-09-2019 15:13 2888958

Цитата:

Цитата Busla
я описал реализацию »

Да что вы говорите?! Отлично!
Самомнение у вас раздуто сильно.
Если уж беретесь кулаком в грудь стучать, то описывайте не косноязычно:
Цитата:

Цитата Busla
Операция массив + что-то возвращает новый массив. »

Такое описание даже на сказку не тянет, не то что на магию, если что...
Что это за операция такая "Плюс что-то"? :)

Цитата:

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

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

Цитата DJ Mogarych
$src = get-process |select name,product,ProductVersion »

Код:

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 21-09-2019 21:25 2888989

Цитата:

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

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

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

Цитата DJ Mogarych
переменные работают как фильтр, а если изменить размер, системе приходится создавать новый объект »

Цитата:

Цитата DJ Mogarych
как объяснить ситуацию, описанную мной в самом начале? »

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

Цитата:

Цитата DJ Mogarych
список процессов, я их помещаю в переменную »

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

DJ Mogarych 22-09-2019 11:05 2889027

Спасибо ВСЕМ, буду осмысливать!

YuS_2 22-09-2019 14:26 2889070

Цитата:

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

В огороде бузина, а в Киеве - дядька.
Не морочьте голову ни себе, ни другим.
Массивы (а у ТС, как раз System.Array) в powershell имеют ссылочный тип (об этом написано в спецификации), о чем и было сказано в самом начале. Вы же полезли в бутылку, чтобы это как-то оспорить - хотя о чем тут спорить? Вы утверждаете, что-то другое? Вижу, что нет. Тогда к чему был ваш комментарий с цитатой моих слов, вы КО? :)
Не надо разводить здесь болота, чтобы пояснить эту простую вещь.
И приплетать Си, Паскаль, да и упоминать синтаксис - абсолютно бессмысленно...

PS
А на счет моего самомнения - вы заблуждаетесь, оно у меня в подписи обозначено.


Время: 20:50.

Время: 20:50.
© OSzone.net 2001-