Реклама
Деревья на Ls?, HowTo?
fedotxxl
сообщение 25:01:2008, 12:06
Сообщение #1

Репутация:     5  



Буянит во мне идея, но недели две не получается реализовать
Смысл:

В начале и в конце каждого Sub'a/Function'a пишется wf.Start / wf.End
В середине можно залогировать какое-либо событие, запусть что-либо (например benchmark - тест производительности)... В итоге нужно получить отчет типа:
Sub1 LogEvent
     Sub2 AnotherLogEvent
Sub1 BenchmarkEvent
Т.е. построить дерево, состоящее из сабов + доп инфа...

Сообщение отредактировал fedotxxl - 25:01:2008, 12:06


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
 
Start new topic
Ответов (1 - 13)
Morpheus
сообщение 25:01:2008, 12:09
Сообщение #2
Вставить ник
Божественный

Иконка группы

Репутация:     65  



где построить?

аа.... кажеться понял... хотя возможно и не так понял
в скрипте ваши сабы зделайте функциями boolean и дальше

if LogEvent then 
     if AnotherLogEvent then...


if BenchmarkEvent then
  ....


--------------------
Буть осторожен в своих желаниях - они могут сбыться
]]>< База знаний Lotus >]]>
]]> ]]>
консультаций по ICQ не даю
Перейти в начало страницы
 
Цитата Цитировать сообщение
Yakov
сообщение 25:01:2008, 17:12
Сообщение #3
Вставить ник
Продвинутый
Иконка группы

Репутация:     15  



В wf.Start передавайте в качестве параметра имя вызывающей процедуры/функции: wf.Start(GetThreadInfo(LSI_THREAD_PROC)).
Или в самом методе wf.Start берите имя вызвавшей процедуры/функции: GetThreadInfo(LSI_THREAD_CALLPROC).
Было бы интресно узнать задачу/цель и взглянуть на пример кода. Есть идеи. (IMG:http://forum.codeby.net/style_emoticons/default/smile.gif)
Перейти в начало страницы
 
Цитата Цитировать сообщение
Akupaka
сообщение 25:01:2008, 19:48
Сообщение #4
Вставить ник
А че я?.. О.о
Иконка группы

Репутация:     61  



желаете-с универсальное логирование получить, да еще и с учетом стека вызовов?.. (IMG:http://forum.codeby.net/style_emoticons/default/smile.gif)

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

Сообщение отредактировал Akupaka - 25:01:2008, 19:52


--------------------
не учите меня плохому...
Перейти в начало страницы
 
Цитата Цитировать сообщение
fedotxxl
сообщение 25:01:2008, 20:38
Сообщение #5

Репутация:     5  



Для: Akupaka
Именно... нужен стек вызовов. lsi_info выдает стек, но это не дело. Если в каждом Sub'e писать Start и End, то мы сможем составить этот стек сами. Другое дело, как правильно это сделать. В этом и вопрос
Логирование я сюда приписал как вариант использования

Для: Yakov
Спасибо, сам знаю.

Для: Morpheus
Мне кажется вы неправильно поняли

Задача: посторить стек вызовов на основе классов, запоминания информации по вызовам. +возможность расширения до логирования, benchmarka и т.д.

В итоге у нас получится, я так понимаю, разветвленное дерево Sub'ов
Нужно вспомнить как строить деревья и принемимо ли это тут


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
fedotxxl
сообщение 26:01:2008, 01:33
Сообщение #6

Репутация:     5  



Удивительно, но какую-то вменяемую хрень я написал
Class wfSubController
    Private scCurrentSub As wfSub
    
    Public Sub Start(ID As String)
        If scCurrentSub Is Nothing Then
            Set scCurrentSub = New wfSub(ID, Nothing)
        Elseif scCurrentSub.ID <> ID Then
            Dim scTempSub As wfSub
            Set scTempSub = New wfSub(ID, scCurrentSub)
            Call scCurrentSub.AddSub(scTempSub)
            Set scCurrentSub = scTempSub
        End If
        Call scCurrentSub.Start
    End Sub
    
    Public Sub End(ID As String)
        If scCurrentSub.ID <> ID Then
            Error 1
            Exit Sub
        End If
        Call scCurrentSub.End
    End Sub
    
    Public Sub GoToPrevSub
        Set scCurrentSub = scCurrentSub.ParentSub
    End Sub
    
End Class

Class wfSub
    Private sID As String
    Private sParentSub As wfSub
    Private sSubs List As wfSub
    Private sActions() As Action
    Private sLevel As Integer
    
    Public Sub New(ID As String, ParentSub As wfSub)
        sID = ID
        If ParentSub Is Nothing Then
            sLevel = 1
        Else
            sLevel = ParentSub.Level + 1
        End If
        
        Set sParentSub = ParentSub
    End Sub
    
    Public Sub AddSub(wfSub As wfSub)
        Set sSubs(wfSub.ID) = wfSub
    End Sub
    
    Public Sub Start
        
    End Sub
    
    Public Sub End
        
    End Sub
    
    Property Get Level
        Level = sLevel
    End Property
    
    Property Get ParentSub
        Set ParentSub = sParentSub
    End Property
    
    Property Get ID
        ID = sID
    End Property
End Class
Это наброски... в дебагере получил очень хороший результат... Прикол в том, что писал наугад... просто писал, почти не думая (IMG:http://forum.codeby.net/style_emoticons/default/blink.gif)
Пример Сабов:
Sub Sub1(sc As wfSubController)
    sc.Start(Lsi_info(2))
    
    Call Sub2(sc)
    
    sc.End(Lsi_info(2))
    sc.GoToPrevSub
End Sub
Есть соображения, что неправильно, как улучшить?
Сейчас проблема - если в самом первом Sub'e вызвать sc.GoToPrevSub, то scCurrentSub станет Nothing... Вобщем утро вечера мудренее


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
Akupaka
сообщение 26:01:2008, 08:34
Сообщение #7
Вставить ник
А че я?.. О.о
Иконка группы

Репутация:     61  



хм... я, наверное, не понимаю в чем смысл... вернее, задачу-то, понял, а вот область применения не "вижу"... (IMG:http://forum.codeby.net/style_emoticons/default/smile.gif)

деревья-то не сложно строить, сложнее их анализировать (IMG:http://forum.codeby.net/style_emoticons/default/smile.gif)
но в чем смысл? получить дерево процедур для дальнейшего анализа?.. других применений не вижу...


--------------------
не учите меня плохому...
Перейти в начало страницы
 
Цитата Цитировать сообщение
Yakov
сообщение 26:01:2008, 10:15
Сообщение #8
Вставить ник
Продвинутый
Иконка группы

Репутация:     15  



Цитата(fedotxxl @ 26:01:2008, 06:33 )
Есть соображения, что неправильно, как улучшить?
]]>*]]>

Выбросить sc.GoToPrevSub. Действия по перемещению указателя осуществлять в sc.End().
Сделать класс wfSubController Singleton'ом, это избавит от необходимости передавать экземпляр всем процедурам.
Убрать аргументы у процедур sc.Start() и sc.End().
Перейти в начало страницы
 
Цитата Цитировать сообщение
fedotxxl
сообщение 26:01:2008, 14:48
Сообщение #9

Репутация:     5  



Для: Yakov
Цитата
Выбросить sc.GoToPrevSub. Действия по перемещению указателя осуществлять в sc.End().
Дело в том, что между sc.End и sc.GoToPrevSub будет стоять метод sc.Process, который будет обрабатывать полученную информацию в случае необходимости... Например, что-либо распечатывать... А если делать этот метод после GoToPrevSub, то саб-то уже другой... впринципе можно запихнуть метод process в End...
Цитата
Убрать аргументы у процедур sc.Start() и sc.End().
Аргументы передаются для контроля - если закрывается процедура отличная от текущей, то ошибка...
Цитата
Сделать класс wfSubController Singleton'ом, это избавит от необходимости передавать экземпляр всем процедурам.
Не очень понял...

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

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

Сообщение отредактировал fedotxxl - 26:01:2008, 14:48


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
Yakov
сообщение 26:01:2008, 20:49
Сообщение #10
Вставить ник
Продвинутый
Иконка группы

Репутация:     15  



Для: fedotxxl
Singleton кратко описан в ]]>Википедии]]>.
Наверное, хотелось бы иметь отладочный лог прогонки агента, тест производительности и т.п., но чтобы всего этого не было в продакшн-версии без переписывания кучи кода. Тогда имеет смысл создать класс "контроллера" с пустыми реализациями методов start() и end() и его подклассы, выполняющие действия по профилированию или записи лога.
Далее код, иллюстрирующий мои замечания. Писал прямо здесь, это только наброски.
Public Class Controller

Private Sub New()
End Sub

Public Sub start()
End Sub

Public Sub stop()
End Sub

End Class

Public Class Logger As Controller

Private sc As wfSubController

Private Sub New()
  Set sc = New wfSubController(...)
End Sub

Public Sub start()
  Call sc.Start(GetThreadInfo(LSI_THREAD_CALLPROC))
End Sub

Public Sub stop()
  Call sc.End(GetThreadInfo(LSI_THREAD_CALLPROC))
  Call sc.Process()
  Call sc.GoToPrevSub()
End Sub

End Class

Public Class Profiler As Controller

'...

End Class

Private theController As Controller

Public Function getController() As Controller
  If theController Is Nothing Then
    Set theController = New Controller() 'New Profiler(), New Logger()
  End If
  Set getController = theController
End Function

Пример клиентского кода.
Sub Initialize
  Call getController().start()
  Call sub1()
  Call sub2()
  Call getController().stop()
End Sub

Sub sub1
  Call getController().start()
  '...
  Call sub11()
  '...
  Call getController().stop()
End Sub

Sub sub11
  Call getController().start()
  '...
  Call getController().stop()
End Sub

Sub sub2
  Call getController().start()
  '...
  Call getController().stop()
End Sub

Изменив одну строчку, получим нужную функциональность.
Кстати, в Lotus есть логгер NotesLog.
И еще замечание. В справке указано:
Цитата
User-defined errors must be in the range of 1000-1999.
Перейти в начало страницы
 
Цитата Цитировать сообщение
fedotxxl
сообщение 27:01:2008, 00:05
Сообщение #11

Репутация:     5  



Для: Yakov
Прости, в ООП я пока не силен, и голова не варит...

1. Для того, чтобы не передавать контроллер как параметр, ты его объявляешь global'ом?
2. Любое общение с контроллером идет через функцию getController?
3. Новая для меня вещь - переменной объявленной как Base класс можно присваивать наследующие классы?
Цитата
Set theController = New Logger()

4. Предположим, что у Logger'a и Profiler'a существуют свои методы, которые не совпадают (например в Logger'e - .Log, в Profiler'e - .Profile)... Тогда я в контроллере определяю все возможные методы, а соотв классах переопределяю только нужные?
5. В итоге при тестировании метод getController() у меня будет выглядеть
Public Function getController() As Logger
    If theController Is Nothing Then
        Set theController = New Logger() 'New Profiler(), New Logger()
    End If
    Set getController = theController
End Function
, а при конечной сдаче
Цитата
Public Function getController() As Controller
If theController Is Nothing Then
Set theController = New Controller() 'New Profiler(), New Logger()
End If
Set getController = theController
End Function
?
6. Я так понял, что такая реализвация позволит мне переключаться между Logger, Profiler и Controller путем переписания двух строк? Есть ли ещё какие преимущества?

Интересно, но задача была несколько другой - написать FrameWork, одной из функций которого было бы удобное логирование и тест на производительность... Включено ли логирование или нет я думал проверять внутри методов

Кстати, посмотрел насколько оправдано использование метода getController только лишь для того, чтобы не писать дополнительную строку проверки на существование класса в начале каждого метода. Получил, что 10000 раз исполнения этого метода занимают .015 сек =) Темная вещь

Сообщение отредактировал fedotxxl - 27:01:2008, 00:08


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
Yakov
сообщение 27:01:2008, 22:27
Сообщение #12
Вставить ник
Продвинутый
Иконка группы

Репутация:     15  



==== к сожалению, случайно закрыл вкладку браузера вместе с постом на три экрана. восстановлю, когда высплюсь. (IMG:http://forum.codeby.net/style_emoticons/default/smile.gif) ====
краткое содержание.

0. Ничего, что в ООП не силен, это проходит.
1. Нет.
2. Да.
3. Да. Один из принципов ООП - полиморфизм.
4. Вариантов море. Один вы озвучили.
5. Да.
6. Да. Разве этого преимущества недостаточно?

Не более 1.5 микросекунд на вызов функции не такое большое время, чтобы его заметить, если вы не робот-андроид.

Сообщение отредактировал Yakov - 27:01:2008, 22:33
Перейти в начало страницы
 
Цитата Цитировать сообщение
fedotxxl
сообщение 27:01:2008, 23:12
Сообщение #13

Репутация:     5  



Для: Yakov
Жду вашего развернутого поста, если не сложно

Цитата
1. Нет.
Как же подругому?
Цитата
3. Да. Один из принципов ООП - полиморфизм.
Гм.. все-равно мне это сложно понять. В чем преимущество?
Цитата
6. Да. Разве этого преимущества недостаточно?
Это очень интересная техника, но мне несколько иное требовалось


--------------------
Перейти в начало страницы
 
Цитата Цитировать сообщение
Yakov
сообщение 9:02:2008, 19:26
Сообщение #14
Вставить ник
Продвинутый
Иконка группы

Репутация:     15  



Для: fedotxxl

Прошу прощения за столь долгое отсутствие.

Судя по последним темам, вы уже далеко продвинулись в своих изыскания. Видимо, ответ в эту тему будет слегка запоздавшим. Поэтому по существу отвечу в соответствующих темах, а здесь приведу несколько полезных, на мой взгляд, книг.

1. ООП и дизайн.
Классика - Гради Буч. Объектно-ориентированный анализ и проектирование.

Паттерны (шаблоны) проектирования - опять же классическая книга "банды четерых" - Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования.
Но эту книгу читать очень тяжело. В принципе, практически в любой книге по UML приводится большое количество паттернов проектирования.
Еще одна очень хорошая книга - Мартин Фаулер. Архитектура корпоративных программных приложений.

2. Рефакторинг (переработка кода).
Мартин Фаулер. Рефакторинг. Улучшение существующего кода.
(Мартин Фаулер вообще очень мощный профессионал. Считаю, что его книги нужно брать не раздумывая. А лучше сразу две: одну самому читать, вторую коллегам/друзьям дарить. См. также ]]>http://martinfowler.com/)]]>
Джошуа Кериевски. Рефакторинг с использованием шаблонов (паттернов проектирования).
Эта книга из серии Martin Fowler Signature Series. После ее прочтения становятся понятны многие паттерны и способы их применения. Must have (как и всю Martin Fowler Signature Series).

3. Измерение производительности и оптимизация кода.
Крис Касперски. Техника оптимизации программ. Эффективное использование памяти.


Еще мощный источник знаний и опыта - исходные коды. И не только лотусовые исходники. К примеру, в java очень хорошая и большая библиотека классов. В ней есть практически все, что нужно.
Существует масса библиотек и инструментов с открытыми исходными кодами, к примеру, Apache log4j для журналирования (проект apache.org).
Я считаю, что чтение исходников - это своего рода обучение программерскому ремеслу (и искусству) у профессионалов. Изучил исходник, проникся, применил к своей задаче (пусть даже на другом ЯП).
Перейти в начало страницы
 
Цитата Цитировать сообщение

Ссылка на тему:
BBCode: 
HTML:      
Fast ReplyReply to this topicStart new topic

 

> Быстрый ответ
 Отправлять уведомления об ответах на e-mail |  Включить смайлики |  Добавить подпись |  AJAX?
   

Свернуть

>

  Тема
Нет новых сообщений Деревья на Pascal
Написать дерево на Паскале
0 Wolfram 73 10:12:2009 - 09:18 Wolfram
Нет новых сообщений АВЛ-деревья
программа удаления записи
0 DUPLET 171 8:05:2009 - 06:27 DUPLET
Нет новых сообщений Dst деревья
1 Cati 376 5:12:2007 - 22:35 Pasha
Закрыта Деревья решений
Построение дерева принятия решения на Delphi
0 -Isilme- 823 10:05:2007 - 16:19 Isilme
Нет новых сообщений Бинарные деревья
6 toxa_2006 2 749 26:11:2006 - 12:20 BiSoN