.. index:: single: Reflection and Meta-programming; Introduction =============================== Reflection and Meta-programming =============================== Since the Ring programming language is a dynamic language, we can get answers about the program code and we can modify our code during the runtime. In this chapter we will learn about this and the available functions to use. .. index:: pair: Reflection and Meta-programming; locals() locals() Function ================= We can get a list of variables names in the current scope using the locals() function. Syntax: .. code-block:: ring locals() --> a list contains the variables names in the current scope Example: .. code-block:: ring test("hello") func test cMsg see cMsg + nl x = 10 y = 20 z = 30 see locals() Output: .. code-block:: ring hello cmsg x y z .. index:: pair: Reflection and Meta-programming; globals() globals() Function ================== We can get a list of variables names in the global scope using the globals() function. Syntax: .. code-block:: ring globals() --> a list contains variables names in the global scope Example: .. code-block:: ring x=10 y=20 z=30 test() func test see "message from test()" + nl + "Global Variables:" + nl see globals() Output: .. code-block:: ring message from test() Global Variables: x y z .. index:: pair: Reflection and Meta-programming; functions() functions() Function ==================== We can get a list of functions names written in the Ring language using the functions() function. Syntax: .. code-block:: ring functions() --> a list contains functions names Example: .. code-block:: ring see functions() func f1 see "f1" + nl func f2 see "f2" + nl func f3 see "f3" + nl Output: .. code-block:: ring f1 f2 f3 .. index:: pair: Reflection and Meta-programming; cfunctions() cfunctions() Function ===================== We can get a list of functions names written in the C language using the cfunctions() function. Syntax: .. code-block:: ring cfunctions() --> a list contains functions names Example: .. code-block:: ring aList = cfunctions() See "Count : " + len(aList) + nl for x in aList see x + "()" + nl next Output: .. code-block:: ring Count : 217 len() add() del() get() clock() ... .. note:: The complete list is removed from the previous output. .. index:: pair: Reflection and Meta-programming; islocal() islocal() Function ================== We can check if a variable is defined in the local scope or not using the islocal() function. Syntax: .. code-block:: ring islocal(cVariableName) --> returns 1 if the variable is defined in the local scope returns 0 if the variable is not defined in the local scope Example: .. code-block:: ring test() func test x=10 y=20 see islocal("x") + nl + islocal("y") + nl + islocal("z") + nl Output: .. code-block:: ring 1 1 0 .. index:: pair: Reflection and Meta-programming; isglobal() isglobal() Function =================== We can check if a variable is defined in the global scope or not using the isglobal() function. Syntax: .. code-block:: ring isglobal(cVariableName) --> returns 1 if the variable is defined in the global scope returns 0 if the variable is not defined in the global scope Example: .. code-block:: ring x=10 y=20 test() func test see isglobal("x") + nl + isglobal("y") + nl + isglobal("z") + nl Output: .. code-block:: ring 1 1 0 .. index:: pair: Reflection and Meta-programming; isfunction() isfunction() Function ===================== We can check if a Ring function is defined or not using the isfunction() function. Syntax: .. code-block:: ring isfunction(cFunctionName) --> returns 1 if the Ring function is defined returns 0 if the Ring function is not defined Example: .. code-block:: ring see isfunction("f1") + nl + isfunction("f2") + nl + isfunction("f3") + nl func f1 see "message from f1()" + nl func f2 see "message from f2()" + nl Output: .. code-block:: ring 1 1 0 .. index:: pair: Reflection and Meta-programming; iscfunction() iscfunction() Function ====================== We can check if a C function is defined or not using the iscfunction() function. Syntax: .. code-block:: ring iscfunction(cFunctionName) --> returns 1 if the C function is defined returns 0 if the C function is not defined Example: .. code-block:: ring see iscfunction("len") + nl + iscfunction("add") + nl + iscfunction("test") + nl Output: .. code-block:: ring 1 1 0 .. index:: pair: Reflection and Meta-programming; packages() packages() Function =================== We can get a list of packages names using the packages() function. Syntax: .. code-block:: ring packages() --> a list contains packages names Example: .. code-block:: ring See packages() Package Package1 Class class1 Func f1 Package Package2 Class class1 Func f1 Package Package3 Class class1 Func f1 Package Package4 Class class1 Func f1 Output: .. code-block:: ring package1 package2 package3 package4 .. index:: pair: Reflection and Meta-programming; ispackage() ispackage() Function ==================== We can check if a package is defined or not using the ispackage() function. Syntax: .. code-block:: ring ispackage(cPackageName) --> returns 1 if the Package is defined returns 0 if the Package is not defined Example: .. code-block:: ring See ispackage("package1") + nl + ispackage("package4") + nl + ispackage("package5") + nl + ispackage("package3") + nl Package Package1 Class class1 Func f1 Package Package2 Class class1 Func f1 Package Package3 Class class1 Func f1 Package Package4 Class class1 Func f1 Output: .. code-block:: ring 1 1 0 1 .. index:: pair: Reflection and Meta-programming; classes() classes() Function ================== We can get a list of classes names using the classes() function. Syntax: .. code-block:: ring classes() --> a list contains classes names Example: .. code-block:: ring See classes() Class class1 Func f1 Class class2 Func f1 Class class3 Func f1 Output: .. code-block:: ring class1 class2 class3 .. index:: pair: Reflection and Meta-programming; isclass() isclass() Function ================== We can check if a class is defined or not using the isclass() function. Syntax: .. code-block:: ring isclass(cClassName) --> returns 1 if the Class is defined returns 0 if the Class is not defined Example: .. code-block:: ring see isclass("class4") + nl + isclass("class3") + nl + isclass("class2") + nl Class class1 func f1 class class2 func f1 class class3 func f1 Output: .. code-block:: ring 0 1 1 .. index:: pair: Reflection and Meta-programming; packagesclasses() packageclasses() Function ========================= We can get a list of classes names inside a package using the packageclasses() function. Syntax: .. code-block:: ring packageclasses(cPackageName) --> a list contains classes names inside the package Example: .. code-block:: ring see "classes in Package1" + nl see packageclasses("Package1") see "classes in Package2" + nl see packageclasses("Package2") Package Package1 Class class1 Func f1 Package Package2 Class class1 Func f1 Class class2 Func f1 Class class3 func f1 Output: .. code-block:: ring classes in Package1 class1 classes in Package2 class1 class2 class3 .. index:: pair: Reflection and Meta-programming; ispackagesclass() ispackageclass() Function ========================= We can check if a class is defined inside package or not using the ispackageclass() function. Syntax: .. code-block:: ring ispackageclass(cPackageName,cClassName) --> returns 1 if the Class is defined returns 0 if the Class is not defined Example: .. code-block:: ring see ispackageclass("package1","class1") + nl + ispackageclass("package1","class2") + nl + ispackageclass("package2","class1") + nl + ispackageclass("package2","class2") + nl Package Package1 Class class1 Func f1 Package Package2 Class class1 Func f1 Class class2 Func f1 Class class3 func f1 Output: .. code-block:: ring 1 0 1 1 .. index:: pair: Reflection and Meta-programming; classname() classname() Function ==================== We can know the class name of an object using the classname() function Syntax: .. code-block:: ring classname(object) --> Returns the object class name Example: .. code-block:: ring o1 = new point o2 = new rect see classname(o1) + nl # print point see classname(o2) + nl # print rect class point class rect .. index:: pair: Reflection and Meta-programming; objectid() objectid() Function =================== We can know the object id using the objectid() function Syntax: .. code-block:: ring objectid(object) --> Returns the object id Example: .. code-block:: ring o1 = new point see objectid(o1) + nl test(o1) func test v see objectid(v) + nl Class point x y z Output: .. code-block:: ring 021B5808 021B5808 .. index:: pair: Reflection and Meta-programming; isobject() isobject() Function =================== We can check the variable to know if it's an object or not using the isobject() function Syntax: .. code-block:: ring isobject(variable) --> Returns True if it's an object, False if it's not .. index:: pair: Reflection and Meta-programming; attributes() attributes() Function ===================== We can get the object attributes using the attributes() function Syntax: .. code-block:: ring attributes(object) --> Returns a list contains the object attributes Example: .. code-block:: ring o1 = new point aList = attributes(o1) # we can use see attributes(o1) for t in aList see t next # print xyz Class Point x y z .. index:: pair: Reflection and Meta-programming; methods() methods() Function ================== We can get the object methods using the methods() function Syntax: .. code-block:: ring methods(object) --> Returns a list contains the object methods Example: .. code-block:: ring o1 = new test aList = methods(o1) for x in aList cCode = "o1."+x+"()" eval(cCode) next Class Test func f1 see "hello from f1" + nl func f2 see "hello from f2" + nl func f3 see "hello from f3" + nl func f4 see "hello from f4" + nl Output: .. code-block:: ring hello from f1 hello from f2 hello from f3 hello from f4 .. index:: pair: Reflection and Meta-programming; isattribute() isattribute() Function ====================== We can test if the object contains an attribute or not using the isattribute() function Syntax: .. code-block:: ring isattribute(object,cAttributeName) --> Returns True if the object contains the attribute Example: .. code-block:: ring o1 = new point see isattribute(o1,"x") + nl # print 1 see isattribute(o1,"t") + nl # print 0 see isattribute(o1,"y") + nl # print 1 see isattribute(o1,"z") + nl # print 1 class point x y z .. index:: pair: Reflection and Meta-programming; isprivateattribute() isprivateattribute() Function ============================= We can test if the object contains a private attribute or not using the isprivateattribute() function Syntax: .. code-block:: ring isprivateattribute(object,cAttributeName) --> Returns True if the object contains the private attribute Example: .. code-block:: ring o1 = new person see isprivateattribute(o1,"name") + nl + isprivateattribute(o1,"address") + nl + isprivateattribute(o1,"phone") + nl + isprivateattribute(o1,"job") + nl + isprivateattribute(o1,"salary") Class Person name address phone private job salary Output: .. code-block:: ring 0 0 0 1 1 .. index:: pair: Reflection and Meta-programming; ismethod() ismethod() Function =================== We can test if the object class contains a method or not using the ismethod() function Syntax: .. code-block:: ring ismethod(object,cMethodName) --> Returns True if the object class contains the method Example: .. code-block:: ring o1 = new point see ismethod(o1,"print") + nl # print 1 mylist = [] mylist + new point see ismethod(mylist[1],"print") + nl # print 1 class point x y z func print see x + nl + y + nl + z + nl .. index:: pair: Reflection and Meta-programming; isprivatemethod() isprivatemethod() Function ========================== We can test if the object class contains a private method or not using the isprivatemethod() function Syntax: .. code-block:: ring isprivatemethod(object,cMethodName) --> Returns True if the object class contains the private method Example: .. code-block:: ring o1 = new Test see isprivatemethod(o1,"f1") + nl + isprivatemethod(o1,"f2") Class Test func f1 see "message from f1()" + nl private func f2 see "message from f2()" + nl Output: .. code-block:: ring 0 1 .. index:: pair: Reflection and Meta-programming; addattribute() addattribute() Function ======================= We can add an attribute (or a group of attributes) to the object state (not the class) using the addattribute() function Syntax: .. code-block:: ring AddAttribute(object,cAttributeName|aAttributesList) Example(1): .. code-block:: ring see new point {x=10 y=20 z=30} Class Point AddAttribute(self,["x","y","z"]) Example(2): .. code-block:: ring o1 = new point addattribute(o1,"x") addattribute(o1,"y") addattribute(o1,"z") see o1 {x=10 y=20 z=30} class point Output: .. code-block:: ring x: 10.000000 y: 20.000000 z: 30.000000 .. index:: pair: Reflection and Meta-programming; addmethod() addmethod() Function ==================== We can add a method to the object class using the addmethod() function This method can be used with any object from the same class. Syntax: .. code-block:: ring AddMethod(Object,cNewMethodName,cMethodName|AnonymousFunction) Example: .. code-block:: ring o1 = new point { x=10 y=20 z=30 } addmethod(o1,"print", func { see x + nl + y + nl + z + nl } ) o1.print() Class point x y z Output: .. code-block:: ring 10 20 30 Instead of using anonymous function to add new method to the class, we can use the function name Example: .. code-block:: ring o1 = new point { x=10 y=20 z=30 } myfunc = func { see x + nl + y + nl + z + nl } addmethod(o1,"print", myfunc ) addmethod(o1,"display", myfunc ) addmethod(o1,"show", myfunc ) o1.print() o1.display() o1.show() Class point x y z Output: .. code-block:: ring 10 20 30 10 20 30 10 20 30 Since we add the method to the class, any object from that class can use this method Example: .. code-block:: ring o1 = new point { x=10 y=20 z=30 } o2 = new point { x=100 y=200 z=300 } o3 = new point { x=50 y=150 z=250 } addmethod(o1,"print", func { see x + nl + y + nl + z + nl } ) o1.print() o2.print() o3.print() Class point x y z Output: .. code-block:: ring 10 20 30 100 200 300 50 150 250 .. index:: pair: Reflection and Meta-programming; getattribute() getattribute() function ======================= We can get the object attribute value using the getattribute() function Syntax: .. code-block:: ring GetAttribute(oObject,cAttributeName) ---> Attribute Value Example: .. code-block:: ring o1 = new point see getattribute(o1,"name") + nl + getattribute(o1,"x") + nl + getattribute(o1,"y") + nl + getattribute(o1,"z") + nl Class Point x=10 y=20 z=30 name = "3D-Point" Output: .. code-block:: ring 3D-Point 10 20 30 Example: We can Find a Class List Member using GetAttribute() using a function findclass() The Find uses the member name, rather than the column number .. code-block:: ring myList = [new Company {position=3 name="Mahmoud" symbol="MHD"}, new Company {position=2 name="Bert" symbol="BRT"}, new Company {position=1 name="Ring" symbol="RNG"} ] see myList see nl +"=====================" + nl + nl for i = 1 to len(myList) see "Pos: "+ i +" | "+ myList[i].position +" | "+ myList[i].name + " | "+ myList[i].symbol +" | "+ nl next See findclass(myList, "MHD", "symbol") +nl ### Specify Member class name ###--------------------------------------- func findclass classList, cValue, classMember See nl + "FindClass: " +" "+ cValue + nl + nl for i = 1 to len(classList) result = getattribute( classList[i], classMember ) See "Result-Attr: " + i +" "+ result +nl if result = cValue j = i ok next return j ###-------------------------------------- class company position name symbol Output: .. code-block:: ring Pos: 1 | 3 | Mahmoud | MHD | Pos: 2 | 2 | Bert | BRT | Pos: 3 | 1 | Ring | RNG | FindClass: MHD Result-Attr: 1 MHD Result-Attr: 2 BRT Result-Attr: 3 RNG 1 .. index:: pair: Reflection and Meta-programming; setattribute() setattribute() function ======================= We can set the object attribute value using the setattribute() function Syntax: .. code-block:: ring SetAttribute(oObject,cAttributeName,Value) Example: .. code-block:: ring o1 = new person setattribute(o1,"cName","Mahmoud") setattribute(o1,"nSalary",1000000) setattribute(o1,"aColors",["white","blue","yellow"]) see o1 see o1.aColors Class Person cName nSalary aColors Output: .. code-block:: ring cname: Mahmoud nsalary: 1000000.000000 acolors: List... white blue yellow .. index:: pair: Reflection and Meta-programming; mergemethods() mergemethods() Function ======================= We can share methods between classes without inheritance using the MergeMethods() function This function merge class methods to another class. Syntax: .. code-block:: ring MergeMethods(cClassNameDestination,cClassNameSource) Example: .. code-block:: ring mergemethods("count","share") mergemethods("count2","share") o1 = new count { test() } o1 = new count2 { test() } Class Share func one see "one" + nl func two see "two" + nl func three see "three" + nl Class Display Func printline see copy("*",20) + nl Class Count from Display Func test printline() one() two() three() printline() Class Count2 from Display Func test three() two() one() printline() Output: .. code-block:: ring ******************** one two three ******************** three two one ********************