Изящный способ вернуть динамическую строку

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3306
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 51 раз
Контактная информация:

Изящный способ вернуть динамическую строку

Сообщение Дед Пахом »

Автор Mike Hanson.

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

                    PROGRAM

                    MAP
                    end

c1                  CLASS
GiveMeAString           Procedure(),String
                    end

    CODE
        
    Message(c1.GiveMeAString())    
        
c1.GiveMeAString    PROCEDURE
LocalClass              CLASS
MyString                    &String
Destruct                    PROCEDURE
                        END

  
    CODE
        
        LocalClass.MyString &= NEW String(100)
        LocalClass.MyString = 'Here it is!'
        Return LocalClass.MyString

LocalClass.Destruct PROCEDURE

    Code
        
        Message('Destructor is killing the string now')
        Dispose(SELF.MyString)
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8090
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 29 раз
Поблагодарили: 98 раз

Изящный способ вернуть динамическую строку

Сообщение Игорь Столяров »

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

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

  Map
    GetVarString(long),*string 
  end

MyString &String

  Code
 
   MyString &= GetVarString(123)
   If ~(MyString &= NULL)
        Message(MyString)
        Dispose(MyString)
   end
   
GetVarString  Procedure(xSize_)
RetString &String
  Code
  RetString &= New(String(xSize_))
  If ~(RetString &= NULL) then RetString = 'Привет лунатикам !'.
  Return RetString
Make Clarion Great Again ! 😎
PavelNK
Старожил
Сообщения: 280
Зарегистрирован: 15 Март 2011, 8:02

Изящный способ вернуть динамическую строку

Сообщение PavelNK »

Тогда уж так

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

  Map
    GetVarString(long),*string 
  end

MyString &String

  Code
 
   If ~(MyString &= NULL)
        Dispose(MyString)
        MyString &= NULL
   end
   MyString &= GetVarString(123)
   If ~(MyString &= NULL)
        Message(MyString)
        Dispose(MyString)
        MyString &= NULL
   end
   
GetVarString  Procedure(xSize_)
RetString &String
  Code
  RetString &= New(String(xSize_))
  If ~(RetString &= NULL) then RetString = 'Привет лунатикам !'.
  Return RetString
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8090
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 29 раз
Поблагодарили: 98 раз

Изящный способ вернуть динамическую строку

Сообщение Игорь Столяров »

Ну это уже из серии "презерватив на свечку". :)
У меня ведь в примере нет использования ЛОКАЛЬНО объявленной переменной MyString, зачем ее сбрасывать ?
А связка

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

        Dispose(MyString)
        MyString &= NULL
оставляет ощущение, что, что одно здесь точно лишнее ... ;)
Make Clarion Great Again ! 😎
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Изящный способ вернуть динамическую строку

Сообщение Yufil »

Насколько я понял, здесь речь о тонкой разнице между
procedure (),*String
......
Return s

и
procedure(),String
......
Return (s)

Если пишется в скобках, выражение разыменовывается, а если без скобок-возвращается адрес.
Если s является ссылкой на строку, эту ссылку можно вернуть в качестве результата.
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3306
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 51 раз
Контактная информация:

Изящный способ вернуть динамическую строку

Сообщение Дед Пахом »

тут проблема в чём: если s ссылка на строку, то

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

s &= NEW STRING(100)
s = 'Here it is'
RETURN (s)
не освобождает выделенную память.
С уважением, ДП
PavelNK
Старожил
Сообщения: 280
Зарегистрирован: 15 Март 2011, 8:02

Изящный способ вернуть динамическую строку

Сообщение PavelNK »

Опыт, сын ошибок трудных, говорит: Надень два, даже если это свечка! Это не трудно и не накладно, зато надежно :lol:
Игорь Столяров писал(а): Ну это уже из серии "презерватив на свечку". :)
У меня ведь в примере нет использования ЛОКАЛЬНО объявленной переменной MyString, зачем ее сбрасывать ?
А связка

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

        Dispose(MyString)
        MyString &= NULL
оставляет ощущение, что, что одно здесь точно лишнее ... ;)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Изящный способ вернуть динамическую строку

Сообщение Yufil »

Дед Пахом писал(а):
s &= NEW STRING(100)
s = 'Here it is'
RETURN (s)

не освобождает выделенную память.
С уважением, ДП
Это просто не сработает, Return(s) вернёт не ссылку на строку, а её значение.
А декларация прописана как

Map
GetVarString(long),*string
end

Но фишку я так и не просёк...
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3306
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 51 раз
Контактная информация:

Изящный способ вернуть динамическую строку

Сообщение Дед Пахом »

Именно о декларации "(), STRING" речь изначально. Фишка в том, что, объявив в процедуре локальный класс с деструктором, можно возвращать по RETURN то, что было создано NEW.
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8090
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 29 раз
Поблагодарили: 98 раз

Изящный способ вернуть динамическую строку

Сообщение Игорь Столяров »

Я бы сказал проще: используется неявный вызов Dispose(SELF.MyString) через LocalClass.Destruct. В этом основная фишка.
Пример действительно интересно показывает, как можно выполнить некий код после оператора RETURN в процедуре,
чего сделать традиционным способом наверное невозможно .... ;)
Make Clarion Great Again ! 😎
Ответить