Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1 2
Bonjour
Comme en java, on devrait pouvoir écrire : n_classe lnvo = create n_classe( "coucou", today() )
Avec PB (sauf peut être PB11), c'est pas possible...
et on doit faire qlq chose comme :
n_classe lnvo lnvo = create n_classe if isValid( lnvo) then lnvo.uf_init('coucou', today() )
Dommage, mais ... on peut s'en rapprocher ...
La 1° astuce, consiste à écrire des fonctions globales et à les utiliser comme ceci:
n_classe lnvo lnvo = f_create( "n_classe", "coucou", today() )
Ok, mais il va falloir écrire n! fonctions globales pour gérer toutes les combinaisons de paramètres :
f_create( nonvisualobject, int)
f_create( nonvisualobject, int, int )
...
f_create( nonvisualobject, string)
...
f_create( nonvisualobject, string, int)
...
fatigant !
La deuxième astuce, c'est d'utiliser le type any et d'écrire une seule fonction globale f_create polymorphe (c'est possible uniquement en mode "edit source"... )
global type f_create from function_object end type forward prototypes global function nonvisualobject f_create (string as_nom_classe, any aa) global function nonvisualobject f_create (string as_nom_classe, any aa1, any aa2) global fun... end prototypes global function nonvisualobject f_create (string as_nom_classe, any aa); nonvisualObject lno lno = create using as_nom_classe if isValid( lno) then lno.dynamic constructeur(aa) return lno end function global function nonvisualobject f_create (string as_nom_classe, any aa1, any aa2); nonvisualObject lno lno = create using as_nom_classe if isValid( lno) then lno.dynamic constructeur(aa1, aa2) return lno end function
La classe "n_classe", doit posséder une fonction « constructeur » avec n paramètres correspondant à l'appel…sinon on a une erreur à l'exécution...
Alors, combien de pépites pour ces 2 astuces ?
Tron
Hors ligne
Tron a écrit:
Alors, combien de pépites pour ces 2 astuces ?
Tron
1 pépite par astuce, car les pépites ne se demandent pas
98 pour le choix de ton pseudo.
Soit 00 pépites
Hors ligne
Ouuuuah !
Hors ligne
Tron a écrit:
La classe "n_classe", doit posséder une fonction « constructeur » avec n paramètres correspondant à l'appel…sinon on a une erreur à l'exécution...
Tron
Si tu remplaces la fonction par un event dans ta classe d'objet, il n'y aura plus d'erreur à l'exécution.
L'appel se fait comme ça : lno.dynamic trigger event constructeur(aa1,aa2,...)
Avantage si le nombre d'arguments de l'event n'est pas le bon ou même si l'event n'existe pas, PB ne plante pas. Et puis un event peut être étendu facilement. Ca ouvre pas mal de perspectives !
Hors ligne
C'est vrai, mais ...
il est parfois interressant d'avoir plusieurs constructeurs avec des paramètres différents
et avec PB,
il est impossible (?) de d'avoir deux event avec le même nom et des arguments différents...
Pour gérér les erreurs j'utilise des try/catch...
Event ou fonction, pour la moi la question reste ouverte...
A+
Hors ligne
Tron a écrit:
C'est vrai, mais ...
il est parfois interressant d'avoir plusieurs constructeurs avec des paramètres différents
et avec PB,
il est impossible (?) de d'avoir deux event avec le même nom et des arguments différents...
Pour gérér les erreurs j'utilise des try/catch...
Event ou fonction, pour la moi la question reste ouverte...
A+
Pour gérer 1 à n paramètres je te conseillerais plus de créer un objet n_param que tu passerais au constructeur. Cet objet n_param, peut contenir en instance un tableau de any ia_param[] et toutes les méthodes nécessaires pour travailler dessus : uf_add_param(as_nom, aa_valeur), uf_read_param(as_nom), etc. Du coup le nombre de paramètres n'est plus limité...
Hors ligne
Un truc comme ça ?
global type s_chrnico from structure long l_array[] string s_array[] double d_array[] date dt_array[] powerobject po_array[] end type
Hors ligne
shahin a écrit:
Un truc comme ça ?
Code: pb
global type s_chrnico from structure long l_array[] string s_array[] double d_array[] date dt_array[] powerobject po_array[] end type
Voilà mon objet.
Il vaut un paquet de pépites celui-là car directement extrait de N2I-LIBRARY.
forward global type n_param from nonvisualobject end type type str_uo_param from structure within n_param end type end forward type str_uo_param from structure any a_param string s_nom end type global type n_param from nonvisualobject end type global n_param n_param type variables Private: str_uo_param istr_param[] end variables forward prototypes public function any uf_get_param (string as_nom) public subroutine uf_set_param (string as_nom, any aa_param) public function long uf_count_param () public function any uf_get_param (long al_pos) public function string uf_get_param_name (long al_pos) public subroutine uf_delete_all_params () public function boolean uf_modify_param (string as_nom, any aa_param) end prototypes public function any uf_get_param (string as_nom);long ll_max, ll_i any la_param ll_max = Upperbound(istr_param[]) for ll_i = 1 to ll_max if trim(upper(istr_param[ll_i].s_nom)) = trim(upper(as_nom)) then la_param = istr_param[ll_i].a_param exit end if next Return la_param end function public subroutine uf_set_param (string as_nom, any aa_param);long ll_max if not uf_modify_param( as_nom, aa_param ) then ll_max = Upperbound(istr_param[]) ll_max++ istr_param[ll_max].a_param = aa_param istr_param[ll_max].s_nom = as_nom end if end subroutine public function long uf_count_param ();return upperbound(istr_param) end function public function any uf_get_param (long al_pos);Return istr_param[al_pos].a_param end function public function string uf_get_param_name (long al_pos);Return istr_param[al_pos].s_nom end function public subroutine uf_delete_all_params ();str_uo_param lstr_vide[] istr_param = lstr_vide end subroutine public function boolean uf_modify_param (string as_nom, any aa_param);long ll_max, ll_i boolean lb_ret ll_max = Upperbound(istr_param[]) for ll_i = 1 to ll_max if trim(upper(istr_param[ll_i].s_nom)) = trim(upper(as_nom)) then istr_param[ll_i].a_param = aa_param lb_ret = True exit end if next Return lb_ret end function on n_param.create call super::create TriggerEvent( this, "constructor" ) end on on n_param.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
Hors ligne
Pourquoi pas, mais ...
dans ce cas tu rajoutes une nouvelle classe ou une structure et ... donc une nouvelle dépendance...
dans l'évent (si tu utilise une structure avec des tableau), tu es obligé d'écrire qq chose comme :
...
ls_xxx = ast_param.s_array[ xxx ]
ll_xxx = ast_param.l_array[ yyy ]
...
c'est moins lisible
Dernière modification par Tron (20-09-2007 09:56:28)
Hors ligne
Tron a écrit:
Pourquoi pas, mais ...
dans ce cas tu rajoutes une nouvelle classe ou une structure et ... donc une nouvelle dépendance...
dans l'évent tu es obligé d'écrire qq chose comme :
...
ls_xxx = ast_param.s_array[ xxx ]
ll_xxx = ast_param.l_array[ yyy ]
...
c'est pas très objet
Non, je récupère les arg comme ça
ls_xxx = a_param.uf_get_param("arg1")
ll_xxx = a_param.uf_get_param("arg2")
Puisque l'objet a ses propres méthodes GET et SET...
Et tes arguments tu les utilises comment dans ta fonction constructeur ?
ls_xxx = string(aa_arg1)
ll_yyy = long(aa_arg2)
...
C'est plus objet ?
Hors ligne
Ce qui me gêne le plus c'est d'ajouter un nouvel objet ....
Hors ligne
Qui peut expliquer l'interet de tout cela ?
Pouvoir ouvrir dynamiquement des users objects ?
Hors ligne
JCZ a écrit:
Pouvoir ouvrir dynamiquement des users objects ?
Pas dynamiquement, au sens ne pas connaitre le nom de la classe à instancier.
Mais de pouvoir ajouter des paramêtres au constructor du NVO.
Par exemple, au lieu d'écrire :
logger = create nvo_logger logger.of_init ("C:\temp\foobar.log", Append!)
On écrirait :
logger = f_create ("nvo_logger", "C:\temp\foobar.log", Append!)
Hors ligne
perso je ne vois pas de problème à utiliser ce genre de script :
logger = create nvo_logger logger.of_init ("C:\temp\foobar.log", Append!)
AMHA la généralisation n'apporte finalement pas grand chose
Hors ligne
Jusqu'au jour où tu vas écrire :
logger = create nvo_logger logger.log ("Hello world")
Chrnico, quelle est la raison qui t'as poussé à écrire cet objet au lieu de faire de la moto ?
Hors ligne
shahin a écrit:
Jusqu'au jour où tu vas écrire :
Code: pb
logger = create nvo_logger logger.log ("Hello world")
Hors ligne
eRaSorZ a écrit:
![]()
![]()
![]()
![]()
J'ai pas été clair ?
Logger est un objet qui sert à écrire dans un fichier texte.
Or, il lui faut savoir dans quel fichier écrire sinon ça marche pas
Hors ligne
Chrnico, deux questions :
1) Ton objet serait-il utilisable en autoinstantiate ?
2 Que pense tu de
forward global type n_ancestor from nonvisualobject end type end forward global type n_ancestor from nonvisualobject event ue_constructor ( readonly n_param ao_param ) end type global n_ancestor n_ancestor event ue_constructor(readonly n_param ao_param);// end event event constructor;// Ancestor for all nvo's who are not autoinstantiate // use f_open in order to open this nvo end event on n_ancestor.create call super::create TriggerEvent( this, "constructor" ) end on on n_ancestor.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
et :
global type f_open from function_object end type forward prototypes global function nonvisualobject f_open (readonly string as_classname, readonly n_param anvo_param) end prototypes global function nonvisualobject f_open (readonly string as_classname, readonly n_param anvo_param); n_ancestor lno lno= create using as_classname lno.Event ue_constructor(anvo_param) return lno end function
Hors ligne
Non mon objet ne peut pas être autoinstanciate car sont état doit être persistant entre le moment où on push les param et le moment ou on les lit. Je pense que vous n'avez pas bien compris l'intérêt de la chose.
Cet objet peut être utilisé partout où vous avez au moins un paramètre à passer à une fonction ou un event.
n_param ln_param ln_param = create n_param ln_param.uf_set_param("nom","toto") ln_param.uf_set_param("age",99) openwithparm(w_truc, ln_param)
Dans la fenêtre appelée...
// déclaré en instance de ma fenêtre n_param in_param in_param = Message.PowerObjectParm if integer(in_param.uf_get_param("age")) > 50 then Messagebox("Erreur", "Monsieur " + string(in_param.uf_get_param("nom")) + " est trop vieux !") end if
Imaginons que nous devions passer un autre paramètre à cette fenêtre. Il suffit de rajouter un ln_param.uf_set_param("param",valeur) avant l'appel de la fonction sans modifier son appel . Imaginez un CloseWithReturn(in_param). Cela permet de contourner le problème de non polymorphisme des events (ou d'écrire 20 prototypes d'une même fonction). Pour ceux qui ne voit toujours pas d'intérêt. Je suis désolé...
Hors ligne
Chrnico a écrit:
Non mon objet ne peut pas être autoinstanciate car sont état doit être persistant entre le moment où on push les param et le moment ou on les lit. Je pense que vous n'avez pas bien compris l'intérêt de la chose.
Cet objet peut être utilisé partout où vous avez au moins un paramètre à passer à une fonction ou un event.
Imaginons que nous devions passer un autre paramètre à cette fenêtre. Il suffit de rajouter un ln_param.uf_set_param("param",valeur) avant l'appel de la fonction sans modifier son appel . Imaginez un CloseWithReturn(in_param). Cela permet de contourner le problème de non polymorphisme des events (ou d'écrire 20 prototypes d'une même fonction). Pour ceux qui ne voit toujours pas d'intérêt. Je suis désolé...
L'intéret d'un tel objet est clair, mais on a un peu dévié de la discussion initiale. Cet objet aurait mérité un post spécifique du genre déclarer et utiliser un objet paramètre
Hors ligne
eRaSorZ a écrit:
Chrnico a écrit:
Non mon objet ne peut pas être autoinstanciate car sont état doit être persistant entre le moment où on push les param et le moment ou on les lit. Je pense que vous n'avez pas bien compris l'intérêt de la chose.
Cet objet peut être utilisé partout où vous avez au moins un paramètre à passer à une fonction ou un event.
Imaginons que nous devions passer un autre paramètre à cette fenêtre. Il suffit de rajouter un ln_param.uf_set_param("param",valeur) avant l'appel de la fonction sans modifier son appel . Imaginez un CloseWithReturn(in_param). Cela permet de contourner le problème de non polymorphisme des events (ou d'écrire 20 prototypes d'une même fonction). Pour ceux qui ne voit toujours pas d'intérêt. Je suis désolé...L'intéret d'un tel objet est clair, mais on a un peu dévié de la discussion initiale. Cet objet aurait mérité un post spécifique du genre déclarer et utiliser un objet paramètre
Non, je répondais au problème d'origine :
1 la fonction constructeur doit obligatoirement exister avec le bon nombre de paramètres => non si c'est un event
2 il faut prototyper une fonction constructeur avec 1 param any, puis une avec 2 param any, puis 3, 4, etc... => non on utilise le fameux objet n_param qui évite un trop grand nombre de prototypage.
L'intérêt d'avoir les arguments au constructeur au lieu d'un of_init après.
C'est que rien ne garantie que lors du of_init l'objet existe toujours
et conceptuellement, se dire que l'objet est contruit avec ses propriétés au lieu de modifier les propriétés après peu avoir du sens. Là je rejoins TRON
Hors ligne
shahin a écrit:
Chrnico, quelle est la raison qui t'as poussé à écrire cet objet au lieu de faire de la moto ?
???
Hors ligne
Chrnico a écrit:
2 il faut code une fonction constructeur avec 1 param any, puis une avec 2 param any, puis 3, 4, etc... => non on utilise le fameux objet n_param qui évite un trop grand nombre de prototypage.
il n'y a pas que des avantages : en gros tu peux passer tout et n'importe quoi à ta fonction
le prototypage permet à la compilation de s'assurer que tous les cas ont été pris en compte
Chrnico a écrit:
L'intérêt d'avoir les arguments au constructeur au lieu d'un of_init après. C'est que rien ne garantie que lors du of_init l'objet existe toujours
et si tu fais ton of_init juste après le create avec un IsValid ? Sur l'utilisation des paramètres de type Any : tu seras obligé de "caster" ensuite (et ça n'est supporté sur toutes les plateformes)
Hors ligne
Sur l'utilisation des paramètres de type Any : tu seras obligé de "caster" ensuite (et ça n'est supporté sur toutes les plateformes)
Sur quelle plateforme le type any n'est-il pas supporté ?
Hors ligne
Pages: 1 2