2011-09-24 23:37
1167人阅读
评论(0)
收藏
举报
fm:
http://blog.csdn.net/huwenqing1971/article/details/3914052
作者:Réal Gagnon
INDIRECT declaration statement enables a function to be called indirectly by simply setting an instance or shared variable. With a simple INDIRECTed variable, we need to provide 2 functions. One to set the value and one to retrieve the value.
- [instance variable]
- public:
- INDIRECT string i_username {of_SetUsername(*value),of_GetUsername()}
-
- private:
- string zis_username
-
- [Powerscript functions]
- function integer of_SetUsername(string as_username)
-
- IF NOT IsNull(as_username) THEN
- zis_username = upper(as_username)
- END IF
- RETURN 1
-
-
- function String of_GetUsername()
- RETURN zis_username
-
- [test code]
-
- // the of_SetUsername() function is called by PB
- i_username = "powerbuilder howto"
-
- // the of_GetUsername() function is called by PB
- MessageBox("username", i_username)
- [instance variable]
- public:
- INDIRECT string i_username {of_SetUsername(*value),of_GetUsername()}
-
- private:
- string zis_username
-
- [Powerscript functions]
- function integer of_SetUsername(string as_username)
-
- IF NOT IsNull(as_username) THEN
- zis_username = upper(as_username)
- END IF
- RETURN 1
-
-
- function String of_GetUsername()
- RETURN zis_username
-
- [test code]
-
- // the of_SetUsername() function is called by PB
- i_username = "powerbuilder howto"
-
- // the of_GetUsername() function is called by PB
- MessageBox("username", i_username)
Here some notes from Jeremy Lakeman (thanks!).
- INDIRECT variables only compile with 2 or 6 functions in the array otherwise the compiler will crash.
- Arguments that start with a * will be replaced by the appropriate value at compile time and all arguments are optional, the compiler wont complain if you don't pass one of the valid values
- Arguments can be supplied in any order
- The compiler will crash if you define a function with an unsuported argument
- Extra identifiers can be passed to each method, but only if they are valid in the context of the calling code
- The argument names are :
string *name the name of the variable (used with INDIRECT array)
any *value the value being assigned
long[] *args the array of array dimensions (used with INDIRECT array) - Where a value is supplied as an argument, the compiler will call any matching method. This means that you could override the set methods to allow multiple types of values to be assigned.
INDIRECT keyword when used with an array is a little bit more tricky, we need to define 6 functions.
In the following example, the INDIRECT array converts its member to uppercase. A userobject is used to hold our INDIRECT array and the 6 required functions.
[EXPORT .sru file, save into a file _n_cst_indirect.sru_ and then IMPORT it in PB]
- $PBExportHeader$n_cst_indirect.sru
- forward
- global type n_cst_indirect from nonvisualobject
- end type
- end forward
-
- global type n_cst_indirect from nonvisualobject
- end type
- global n_cst_indirect n_cst_indirect
-
- type variables
-
- indirect string x[] {&
- of_set_array(*name, *value), &
- of_set_item(*name, *args, *value), &
- of_get_array(*name), &
- of_get_item(*name, *args), &
- of_upperbound(), &
- of_lowerbound()}
-
- private:
- string ix[]
-
- end variables
- forward prototypes
- public function integer of_lowerbound ()
- public function integer of_upperbound ()
- private function any of_get_array (string s)
- private function string of_get_item &
- (string s, long al_dimensions[])
- private subroutine of_set_item &
- (string s, long al_dimensions[], string as_value)
- private subroutine of_set_array (string s, string as_values[])
- end prototypes
-
- public function integer of_lowerbound ();
- // provide the lower bound of the array
- // can be defined with a *value argument
- // but then must be called by lowerbound(x, 1)
- // this method must be public
-
- return lowerbound(ix)
- end function
-
- public function integer of_upperbound ();
- // provide the upper bound of the array
- // can be defined with a *value argument
- // but then must be called by upperbound(x, 1)
- // this method must be public
-
- return upperbound(ix)
- end function
-
- private function any of_get_array (string s);
- // return the entire array in an any variable
- any la_ret
-
- la_ret=ix
- return la_ret
- end function
-
- private function string of_get_item &
- (string s, long al_dimensions[]);
- // get an element of the array
- return ix[al_dimensions[1]]
- end function
-
- private subroutine of_set_item &
- (string s, long al_dimensions[], string as_value);
- // set an element of the array
- ix[al_dimensions[1]]=upper(as_value)
- end subroutine
-
- private subroutine of_set_array (string s, string as_values[]);
- integer i
- String ls_blank[]
-
- ix = ls_blank
- // set the entire array
- FOR i = 1 TO upperbound(as_values)
- x[i] = as_values[i]
- NEXT
- end subroutine
-
- on n_cst_indirect.create
- call super::create
- TriggerEvent( this, "constructor" )
- end on
-
- on n_cst_indirect.destroy
- TriggerEvent( this, "destructor" )
- call super::destroy
- end on
- To use the userobject from Powerscript :
- integer i
- n_cst_indirect lnv_i
- String tmp[] = &
- { "the uppercase conversion", &
- "was done with the", &
- "INDIRECT keyword!"}
-
- lnv_i = create n_cst_indirect
- lnv_i.x[1] = "powerbuilder howto"
- MessageBox("", lnv_i.x[1])
-
- lnv_i.x[2] = "http://www."
- MessageBox("", lnv_i.x[2])
-
- Messagebox("", string(upperbound(lnv_i.x)))
-
- lnv_i.x = tmp
- FOR i = 1 TO Upperbound(lnv_i.x)
- MessageBox("", lnv_i.x[i])
- NEXT
- $PBExportHeader$n_cst_indirect.sru
- forward
- global type n_cst_indirect from nonvisualobject
- end type
- end forward
-
- global type n_cst_indirect from nonvisualobject
- end type
- global n_cst_indirect n_cst_indirect
-
- type variables
-
- indirect string x[] {&
- of_set_array(*name, *value), &
- of_set_item(*name, *args, *value), &
- of_get_array(*name), &
- of_get_item(*name, *args), &
- of_upperbound(), &
- of_lowerbound()}
-
- private:
- string ix[]
-
- end variables
- forward prototypes
- public function integer of_lowerbound ()
- public function integer of_upperbound ()
- private function any of_get_array (string s)
- private function string of_get_item &
- (string s, long al_dimensions[])
- private subroutine of_set_item &
- (string s, long al_dimensions[], string as_value)
- private subroutine of_set_array (string s, string as_values[])
- end prototypes
-
- public function integer of_lowerbound ();
- // provide the lower bound of the array
- // can be defined with a *value argument
- // but then must be called by lowerbound(x, 1)
- // this method must be public
-
- return lowerbound(ix)
- end function
-
- public function integer of_upperbound ();
- // provide the upper bound of the array
- // can be defined with a *value argument
- // but then must be called by upperbound(x, 1)
- // this method must be public
-
- return upperbound(ix)
- end function
-
- private function any of_get_array (string s);
- // return the entire array in an any variable
- any la_ret
-
- la_ret=ix
- return la_ret
- end function
-
- private function string of_get_item &
- (string s, long al_dimensions[]);
- // get an element of the array
- return ix[al_dimensions[1]]
- end function
-
- private subroutine of_set_item &
- (string s, long al_dimensions[], string as_value);
- // set an element of the array
- ix[al_dimensions[1]]=upper(as_value)
- end subroutine
-
- private subroutine of_set_array (string s, string as_values[]);
- integer i
- String ls_blank[]
-
- ix = ls_blank
- // set the entire array
- FOR i = 1 TO upperbound(as_values)
- x[i] = as_values[i]
- NEXT
- end subroutine
-
- on n_cst_indirect.create
- call super::create
- TriggerEvent( this, "constructor" )
- end on
-
- on n_cst_indirect.destroy
- TriggerEvent( this, "destructor" )
- call super::destroy
- end on
- To use the userobject from Powerscript :
- integer i
- n_cst_indirect lnv_i
- String tmp[] = &
- { "the uppercase conversion", &
- "was done with the", &
- "INDIRECT keyword!"}
-
- lnv_i = create n_cst_indirect
- lnv_i.x[1] = "powerbuilder howto"
- MessageBox("", lnv_i.x[1])
-
- lnv_i.x[2] = "http://www."
- MessageBox("", lnv_i.x[2])
-
- Messagebox("", string(upperbound(lnv_i.x)))
-
- lnv_i.x = tmp
- FOR i = 1 TO Upperbound(lnv_i.x)
- MessageBox("", lnv_i.x[i])
- NEXT
The same technique but this time, our array type is long.
- $PBExportHeader$n_cst_indirect.sru
- forward
- global type n_cst_indirect from nonvisualobject
- end type
- end forward
-
- global type n_cst_indirect from nonvisualobject
- end type
- global n_cst_indirect n_cst_indirect
-
- type variables
-
- indirect long x[] {&
- of_set_array(*name, *value), &
- of_set_item(*name, *args, *value), &
- of_get_array(*name), &
- of_get_item(*name, *args), &
- of_upperbound(), &
- of_lowerbound()}
-
- private:
- long ix[]
-
- end variables
-
- forward prototypes
- public function integer of_lowerbound ()
- public function integer of_upperbound ()
- private function any of_get_array (string s)
- private subroutine of_set_array (string s, long al_values[])
- private function long of_get_item (string s, long al_dimensions[])
- private subroutine of_set_item &
- (string s, long al_dimensions[], long al_value)
- end prototypes
-
- public function integer of_lowerbound ();
- return lowerbound(ix)
- end function
-
- public function integer of_upperbound ();
- return upperbound(ix)
- end function
-
- private function any of_get_array (string s);
- any la_ret
-
- la_ret=ix
- return la_ret
- end function
-
- private subroutine of_set_array (string s, long al_values[]);
- ix=al_values
- end subroutine
-
- private function long of_get_item (string s, long al_dimensions[]);
- return ix[al_dimensions[1]]
- end function
-
- private subroutine of_set_item &
- (string s, long al_dimensions[], long al_value);
- ix[al_dimensions[1]]=al_value
- end subroutine
-
- on n_cst_indirect.create
- call super::create
- TriggerEvent( this, "constructor" )
- end on
-
- on n_cst_indirect.destroy
- TriggerEvent( this, "destructor" )
- call super::destroy
- end on
- $PBExportHeader$n_cst_indirect.sru
- forward
- global type n_cst_indirect from nonvisualobject
- end type
- end forward
-
- global type n_cst_indirect from nonvisualobject
- end type
- global n_cst_indirect n_cst_indirect
-
- type variables
-
- indirect long x[] {&
- of_set_array(*name, *value), &
- of_set_item(*name, *args, *value), &
- of_get_array(*name), &
- of_get_item(*name, *args), &
- of_upperbound(), &
- of_lowerbound()}
-
- private:
- long ix[]
-
- end variables
-
- forward prototypes
- public function integer of_lowerbound ()
- public function integer of_upperbound ()
- private function any of_get_array (string s)
- private subroutine of_set_array (string s, long al_values[])
- private function long of_get_item (string s, long al_dimensions[])
- private subroutine of_set_item &
- (string s, long al_dimensions[], long al_value)
- end prototypes
-
- public function integer of_lowerbound ();
- return lowerbound(ix)
- end function
-
- public function integer of_upperbound ();
- return upperbound(ix)
- end function
-
- private function any of_get_array (string s);
- any la_ret
-
- la_ret=ix
- return la_ret
- end function
-
- private subroutine of_set_array (string s, long al_values[]);
- ix=al_values
- end subroutine
-
- private function long of_get_item (string s, long al_dimensions[]);
- return ix[al_dimensions[1]]
- end function
-
- private subroutine of_set_item &
- (string s, long al_dimensions[], long al_value);
- ix[al_dimensions[1]]=al_value
- end subroutine
-
- on n_cst_indirect.create
- call super::create
- TriggerEvent( this, "constructor" )
- end on
-
- on n_cst_indirect.destroy
- TriggerEvent( this, "destructor" )
- call super::destroy
- end on
Array with multi-dimensions needs functions with different signatures :
- $PBExportHeader$n_cst_indirect.sru
- forward
- global type n_cst_indirect from nonvisualobject
- end type
- end forward
-
- global type n_cst_indirect from nonvisualobject
- end type
- global n_cst_indirect n_cst_indirect
-
- type variables
-
- indirect long x[1,2,3] {&
- of_set_array(*name, *value, *eoseq), &
- of_set_item(*name, *nargs, *args, *value, *eoseq), &
- of_get_array(*name, *eoseq), &
- of_get_item(*name, *nargs, *args, *eoseq), &
- of_upperbound(*dims), &
- of_lowerbound(*dims)}
-
- private:
- long ix[]
-
- /*
- indirect variables only compile with 2 or 6 functions in the array
- otherwise the compiler will crash
-
- arguments that start with a * will be replaced by the appropriate
- value at compile time
- all arguments are optional, the compiler wont complain if you don't
- expect one of the valid values
- arguments can be supplied in any order
- the compiler will crash if you define a function with an unsuported
- argument
- extra identifiers can be passed to each method, but only if they are
- valid in the context of the calling code
- Eg you could pass "this" as an argument
-
- string *name the name of the variable
- any *value the value being assigned
- long[] *args the array of array dimensions
- long *nargs the number of elements in *args
- boolean *eoseq end of sequence
- used to indicate if this is the end of a dot notation
- sequence
- integer *dims dimension for lower or upper bound?
- the compiler doesn't seem to care which named value
- you actually use though
-
- Where a value is supplied as an argument, the compiler will call any
- matching method. This means that you could override the set methods
- to allow multiple types of values to be assigned.
- */
-
- end variables
- forward prototypes
- public function integer of_upperbound (integer al_dims)
- public function integer of_lowerbound (integer al_dims)
- private subroutine of_set_array &
- (string as_name, long al_values[], boolean ab_eoseq)
- private function any of_get_array (string as_name, boolean ab_eoseq)
- private function long of_get_item &
- (string as_name, long al_n_dimensions, &
- long al_dimensions[], boolean ab_eo_seq)
- private subroutine of_set_item &
- (string as_name, long al_n_dimensions, &
- long al_dimensions[], long al_value, boolean ab_eoseq)
- end prototypes
-
- public function integer of_upperbound (integer al_dims);
- // provide the upper bound of the array
- // can be defined with a * argument doesn't seem to care which one
- // but then must be called by upperbound(x, 1)
- // this method must be public
-
- return upperbound(ix)
- end function
-
- public function integer of_lowerbound (integer al_dims);
- // provide the lower bound of the array
- // can be defined with a * argument doesn't seem to care which one
- // but then must be called by lowerbound(x, 1)
- // this method must be public
-
- return lowerbound(ix)
- end function
-
- private subroutine of_set_array &
- (string as_name, long al_values[], boolean ab_eoseq);
- // set the entire array
- ix=al_values
- end subroutine
-
- private function any of_get_array (string as_name, boolean ab_eoseq);
- // return the entire array in an any variable
- any la_ret
-
- la_ret=ix
- return la_ret
- end function
-
- private function long of_get_item &
- (string as_name, long al_n_dimensions, long al_dimensions[],&
- boolean ab_eo_seq);
- // get an element of the array
- return ix[al_dimensions[1]]
- end function
-
- private subroutine of_set_item &
- (string as_name, long al_n_dimensions, long al_dimensions[], &
- long al_value, boolean ab_eoseq);
- // set an element of the array
- ix[al_dimensions[1]]=al_value
- end subroutine
-
- on n_cst_indirect.create
- call super::create
- TriggerEvent( this, "constructor" )
- end on
-
- on n_cst_indirect.destroy
- TriggerEvent( this, "destructor" )
- call super::destroy
- end on
|