This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Код притянут за уши, но смысл его примерно такой. Есть некий базовый класс данных (LCL_ABSTRACT_DATA). От него наследуется конкретный класс с конкретными данными (LCL_DATA).Данные тут таблица целых чисел. Для простоты она сделана публичной. Также есть метод PRINT, который выводит содержимое таблицы на экран.
Также есть некий абстрактный обработчик данных (LCL_ABSTRACT_PROCESSOR), который при создании на вход получает ссылку на инстанцию класса с данными и сохраняет ее у себя в атрибуте (MO_DATA).
От него наследуется обработчик для конкретных данных (LCL_PROCESSOR), который работает именно с LCL_DATA. Для этого внутри своих методов он приводит ссылку на LCL_ABSTRACT_DATA к ссылке на LCL_DATA и работает именно с ней. У него есть 3 разных метода (PROCESS,PROCESS2,PROCESS3), где приведение происходит разными способами. И это, как говорится, влияет! В остальном методы делают одно и тоже - прибавляют 1 к каждому числу в таблице
В начале программы создается класс с данными и заполняется двумя числами 1 и 2.
Далее создается класс процессора, куда передается ссылка на созданный класс с данными, после чего выводится начальное содежимое таблицы класса с данными. Далее последовательно вызываются методы PROCESS,PROCESS2,PROCESS3 у процессора и после каждого вызова происходит вывод текущего состояния таблицы с данными на экран.
Здесь вначале вызывается метод lcl_data=>cast для приведения ссылки на LCL_ABSTRACT_DATA к ссылке на LCL_DATA. Полученная ссылка запоминается в переменной LO_DATA. После чего идет цикл по LO_DATA->MT_DATA и к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 2 и 3: (1,2) + 1 -> (2,3). Забегая вперед - так и есть. Тут все работает.
Здесь вначале для приведения ссылки используется конструкция CAST lcl_data( mo_data ) непосредственно в теле цикла. В логике все то же самое - к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 3 и 4: (2,3) + 1 -> (3,4). Забегая вперед - так и есть. Тут тоже все работает.
Здесь вначале для приведения ссылки используется конструкция lcl_data=>cast( mo_data ) как и в первом методе, но ссылка предварительно не запоминается, а результат вызова метода CAST используется непосредственно в теле цикла. В логике все то же самое - к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 4 и 5: (3,4) + 1 -> (4,5). И вот тут все не так.
Вот как выглядит вывод программы:
Как видите, последний метод почему-то не меняет данные в таблице, хотя в отладке все вроде происходит: 3 становится 4, а 4 становится 5. Но после выхода из цикла эти изменения испаряются. Такое чувство, что в этом случае создается какая-то локальная копия класса именно для цикла и изменения происходят в ней. После чего она благополучно поглощается сборщиком мусора. И главное не понятно по какой причине. Да, returning возращает value, то есть, значение, а не ссылку, но это значение и содержит ссылку. Ну, то есть, даже если это копия оригинальной ссылки, то указывать-то она все равно должна на то же самое!
В общем толи я чего-то не понимаю, толи это баг в SAP.
Часто в регламентах на разработку или в BestPracties нас пугают тем, что писать SELECT * - это плохо. Аргументируется это тем, что не надо выбирать лишнии данные чтобы избегать проблем с производительностью (передача большего числа полей из БД понятно приводит к замедлению этого процесса) и занимаемой памятью (понятно что переденное где то в итоге хранится). И аргументация правильная, но не многие знают, что SELECT * не всегда выбирает все поля.