What follows below is an error that I have encountered. It is mostly a user error (not understanding the translation process) problem. But in part could be ameliorated with an appropriate warning message in the Unicon compiler.

Just an aside, I have downloaded the latest svn source, and the version date has not changed. Under what circumstances does this change?

unicon -version
Unicon Version 12.1.  April 13, 2013


unicon -features
UNIX
POSIX
DBM
ASCII
co-expressions
concurrent threads
dynamic loading
environment variables
event monitoring
external functions
keyboard functions
large integers
multiple programs
pipes
pseudo terminals
system function
messaging
graphics
3D graphics
X Windows
libz file compression
PNG images
CCompiler gcc 4.7.2
Revision 3516
Arch x86_32
Binaries at /home/bruce/unicon/bin/


Error being reported. I have a test program in which I have created a class A which contains a method A. I get the following error when running the class call the first time.

 ./testClassObject

Run-time error 107
File testClassObject.icn; Line 53
record expected
offending value: &null
Traceback:
   main()
   A() from line 6 in testClassObject.icn
   A_initially(object A_1()) from line 85 in testClassObject.icn
   A_A(object A_1(),&null) from line 61 in testClassObject.icn
   {&null . A} from line 53 in testClassObject.icn

The relevant code files are attached. Hopefully the code will make sense. It is part of a CSG code development that I am doing. At the moment, I am building a set of test files for each of the classes. From my understanding, there should be no conflicts between the method name and the name of the class itself.

Just having a further look at the problem, this using the -E option, I notice that if attempting to access the class name when you have a class name the same as a method name, it finds the method name.

Hence, it may be worth adding a warning that there is a method name the same as the class name. Admittedly, this is only a problem if you are creating a singleton, which is the case that I am doing here.

Lastly, for Clinton. Would you mind having a quick look at the code and giving me a critique in terms of whether you would want to have such code available in the IPL or UPL? If and only if you find it applicable or interesting, we can continue this via email. If it doesn't look appropriate, I'll just keep it in my private code base.

At any rate, to all a good night and an interesting week ahead. Hopefully, you are having better weather than the rain and wind we are experiencing here tonight. Wind's blowing and rain's pouring.

regards

Bruce Rennie

########################################################################
#                                                                      #
# file : classobject.icn                                               #
#                                                                      #
# Author : Bruce Rennie                                                #
# Date   : 11-July-2013                                                #
#                                                                      #
# Purpose: This provides a generalised object value and object algebra #
#          facility for use in other classes and objects. It is based  #
#          on the Error class for common error handling facilities.    #
#                                                                      #
#                                                                      #
# Conventions:                                                         #
#    Private fields start with __                                      #
#    Private methods start with _ or __                                #
#                                                                      #
#    Private classes start with __                                     #
#    Private classes have an associated Public Class                   #
#                                                                      #
########################################################################
#                                                                      #
# Public Classes:                                                      #
#                                                                      #
#    class ClassObject : Error()                                       #
#    class ClassClass : ClassObject()                                  #
#                                                                      #
########################################################################
#                                                                      #
# Private Classes:                                                     #
#                                                                      #
########################################################################
#                                                                      #
# Private Fields:                                                      #
#                                                                      #
########################################################################
#                                                                      #
# Public Fields:                                                       #
#                                                                      #
########################################################################
#                                                                      #
# Private Methods:                                                     #
#                                                                      #
#  class ClassClass                                                    #
#    __InitClass()          -> returns the name of the originating     #
#                              class                                   #
#                                                                      #
########################################################################
#                                                                      #
# Public Methods:                                                      #
#                                                                      #
#  Inherit from class Error()                                          #
#    StopMessage(param[])   -: Halts program with message param[]      #
#    PrintMessage(param[])  -: Print message param[] onto current      #
#                              error file (default &errout)            #
#    Caller()               -> name of procedure or method that has    #
#                              called the current procedure            #
#    ProcedureCalling(level)                                           #
#                           -> name of procedure that has called       #
#                              the current procedure                   #
#    ClassCalling(level)    -> name of the class that has called the   #
#                              current procedure                       #
#    MethodCalling(level)   -> name of the method that has called the  #
#                              current procedure                       #
#    ParamCalling(level)    -> the list of parameters from the calling #
#                              procedure                               #
#    CallingComponents(name)                                           #
#                           -> return a list containing the components #
#                              the calling procedure or class/method   #
#    Debug(mode)            -: sets whether the Debug mode is on or    #
#                              for all methods that test this          #
#    DebugMode()            -> succeeds if debug mode is on, fails if  #
#                              debug mode if off                       #
#    ErrorOut(errorfile, writeappend)                                  #
#                           -> Sets the errorout file to be used,      #
#                              if called with no parameters, sets to   #
#                              &errout, otherwise if a string, opens   #
#                              the specified file based on writeappend #
#                              ("w" for write, "a" for append, default #
#                              is "w"), if errorfile is an open file,  #
#                              the output will be sent to this file    #
#                                                                      #
#                   ######################                             #
#            classes and method found in this file                     #
#                                                                      #
#  class ClassObject                                                   #
#    New(objectparams[])    -> return a new object of the private      #
#                              object class associated with the public #
#                              class class                             #
#    Copy()                 -> returns a copy of the calling object    #
#    ClassName()            -> returns the name of the public class    #
#                              to which the current object private     #
#                              is associated with                      #
#                                                                      #
#  class ClassClass                                                    #
#    SetClass(obj)          -: sets the associated private object      #
#                              class to the public class class         #
#                                                                      #
########################################################################
#                                                                      #
# Public Procedures:                                                   #
#    IsObjectOf(val, expectedtypes[])                                  #
#                           -> tests if the object is a member of any  #
#                              of the supplied public class names. Any #
#                              object belonging to a subclass is a     #
#                              member of the superclass, on success it #
#                              returns the name of the public class    #
#                              this object belongs                     #
#    IsObject(val)          -> tests if value given is an object of    #
#                              any kind and on success returns the     #
#                              of the public class this object belongs #
#                              to                                      #
#    ObjectProperties(objectorclassname)                               #
#                           -> a generator returning the field names   #
#                              and method names available to an object #
#                              or to the string name of a public class #
#                              class                                   #
#    AlreadyRun(obj)        -> succeeds if a public class class has    #
#                              been run and converted to a singleton   #
#                              object representing the public class    #
#                              class                                   #
#    SuperClass(obj)        -> returns a list containing all the names #
#                              of the superclasses for this obj.       #
#                              Private class names are converted to    #
#                              associated public class name            #
#    DeepCopy(obj)          -> returns a copy of the value or object   #
#                              given. The copy process is applied to   #
#                              levels of the object, including any and #
#                              structures found in the object          #
#                                                                      #
########################################################################

# required link statements
link ximage
link equiv
link numbers

link error

# required import statements
import lang

# required global statements
global __ClassToObject, __ObjectToClass

# class ClassClass - This class is used as a parent of all classes that 
#                    provide general facilities for an associated object
#                    class
#
# An example is to be found in the Matrix class and associated matrix 
# objects
# 
class ClassClass : ClassObject()

    method SetClass(obj)
        local procname, objname, objID, i := 0
        static type
        initial {
            type := proc("type", 0)
            /__ClassToObject := table()
            /__ObjectToClass := table()
        }
        objID := __InitClass()
        image(obj) ? {="procedure "; objname := tab(0) }
        __ObjectToClass[objname] := objID
        __ObjectToClass[objID] := objID
        __ObjectToClass[trim(objname, "_", 0)] := objID
        if type(obj) == "procedure" then {
            __ClassToObject[objID] := obj
        } else
            if procname := classname(obj) then {
                __ClassToObject[objID] := proc(procname)
            } else
                if type(obj) == "string" then {
                    __ClassToObject[objID] := proc(obj)
                } else
                    StopMessage("Unable to set the Class object creator:", 
ximage(obj))
    end
    
    method __InitClass()
        local classId, i := 0
        while classId := ClassCalling(i +:= 1)
        return classId
    end
    
initially()
    if not AlreadyRun(ClassClass) then {
        self.ClassObject.initially()
        ClassClass := self
    }
end

# class ClassObject - This is the parent object for object classes that 
#                     have an associated operations class
#
class ClassObject : Error()

    method New(objectparams[])
        local printargs := "", i := 0, name, func
        name := ClassName()
        /__ClassToObject := table()
        /__ObjectToClass := table()
        if func := \__ClassToObject[name] then
            return func ! objectparams
        else
            if not DebugMode() then
                return fail
            else {
                every printargs ||:= "Parameter " || (i +:= 1) || ": " || 
ximage(!objectparams) || "\n"
                StopMessage("When creating Object of ", name, 
                            " one or more arguments were incorrect:\n", 
printargs)
            }
    end
    
    method Copy()
        return DeepCopy(self)
    end
    
    method ClassName()
        local name := classname(self)
        return \__ObjectToClass[name] 
    end
        
initially()
    if not AlreadyRun(Error) then
        self.Error.initially()
    if not AlreadyRun(ClassObject) then {
        /__ClassToObject := table()
        /__ObjectToClass := table()
        ClassObject := self
    }
end

# procedure IsObjectOf(val, expectedtypes[])
procedure IsObjectOf(val, expectedtypes[])
    local tx, parentclass, p, pc1
    static type
    initial {
        type := proc("type", 0)
    }
    image(val) ? { ="record"; tx := tab(0)}
    parentclass := SuperClass(val)
    /parentclass := []
    pc1 := []
    every p := !parentclass do {
        #write(p)
        put(pc1, \__ObjectToClass[p] | p)
    }
    push(pc1, classname(val) & val.ClassName()) 
    if \tx & \classname(val) & (!pc1 == !expectedtypes) then
        return val.ClassName()
    else
        fail
end

# procedure IsObject(val)
procedure IsObject(val)
    local tx
    static type
    initial {
        type := proc("type", 0)
    }
    image(val) ? { ="record"; tx := tab(0)}
    if \tx & \classname(val) then
        return classname(val)
    else
        fail
end

# procedure ObjectProperties(object-or-classname)
procedure ObjectProperties(objectorclassname)
    local membname, methname, clname
    static type
    initial {
        type := proc("type", 0)
    }
    if type(objectorclassname) == "string" then {
        clname := proc(objectorclassname, 0)
        if type(clname) ~== "procedure" then
            clname := &null
    } else
        clname := (IsObject(objectorclassname) & objectorclassname)
    if \clname then {
        suspend [!membernames(clname), "member"]
        suspend [!methodnames(clname), "procedure"]
    } else
        fail
end

procedure AlreadyRun(obj)
    return IsObject(obj)
end

procedure SuperClass(obj)
    local l, i, m, o, fn, f
    static type
    initial {
        type := proc("type", 0)
    }
    if IsObject(obj) then {
        l := []
        o := oprec(obj)
        f := []
        every put(f, fieldnames(o))
        every i := 1 to *f do {
            m := o[i]
            fn := f[i]
            if type(m) ~== "procedure" then
                put(l, fn)
        }
        return l
    }
end

procedure DeepCopy(obj)
    local y, k
    static type
    initial {
        type := proc("type", 0)
    }
    case type(obj) of {
        "integer" | "real" | "string" | "cset" | "file" | "window" : 
            return obj
        "set" : {
            y := set()
            every insert(y, DeepCopy(!obj))
        }
        default : {
            y := copy(obj)
            every k := key(obj) do {
                if not (k == ("__s" | "__m")) then 
                    y[k] := DeepCopy(obj[k])
                else if k == "__s" then
                    y[k] := y
            }
        }    
    }
    return y
end
    
    
    
    
    
    
    
    
    
    
########################################################################
#                                                                      #
# file : error.icn                                                     #
#                                                                      #
# Author : Bruce Rennie                                                #
# Date   : 11-July-2013                                                #
#                                                                      #
# Purpose:  To provide a class that provides a set of common error     #
#           handling facilities.                                       #
#                                                                      #
#                                                                      #
#                                                                      #
#                                                                      #
#                                                                      #
#                                                                      #
#                                                                      #
# Conventions:                                                         #
#    Private fields start with __                                      #
#    Private methods start with _ or __                                #
#                                                                      #
#    Private classes start with __                                     #
#    Private classes have an associated Public Class                   #
#                                                                      #
########################################################################
#                                                                      #
# Public Classes:                                                      #
#                                                                      #
#    class Error()                                                     #
#                                                                      #
########################################################################
#                                                                      #
# Private Classes:                                                     #
#                                                                      #
########################################################################
#                                                                      #
# Private Fields:                                                      #
#                                                                      #
########################################################################
#                                                                      #
# Public Fields:                                                       #
#                                                                      #
########################################################################
#                                                                      #
# Private Methods:                                                     #
#                                                                      #
########################################################################
#                                                                      #
# Public Methods:                                                      #
#                                                                      #
#    StopMessage(param[])   -: Halts program with message param[]      #
#    PrintMessage(param[])  -: Print message param[] onto current      #
#                              error file (default &errout)            #
#    Caller()               -> name of procedure or method that has    #
#                              called the current procedure            #
#    ProcedureCalling(level)                                           #
#                           -> name of procedure that has called       #
#                              the current procedure                   #
#    ClassCalling(level)    -> name of the class that has called the   #
#                              current procedure                       #
#    MethodCalling(level)   -> name of the method that has called the  #
#                              current procedure                       #
#    ParamCalling(level)    -> the list of parameters from the calling #
#                              procedure                               #
#    CallingComponents(name)                                           #
#                           -> return a list containing the components #
#                              the calling procedure or class/method   #
#    Debug(mode)            -: sets whether the Debug mode is on or    #
#                              for all methods that test this          #
#    DebugMode()            -> succeeds if debug mode is on, fails if  #
#                              debug mode if off                       #
#    ErrorOut(errorfile, writeappend)                                  #
#                           -> Sets the errorout file to be used,      #
#                              if called with no parameters, sets to   #
#                              &errout, otherwise if a string, opens   #
#                              the specified file based on writeappend #
#                              ("w" for write, "a" for append, default #
#                              is "w"), if errorfile is an open file,  #
#                              the output will be sent to this file    #
#                                                                      #
########################################################################
#                                                                      #
# Public Procedures:                                                   #
#                                                                      #
########################################################################

# required link statements

# required import statements

# required global statements
global __DebugMode, __ErrorOutFile

# class Error
class Error()

    method StopMessage(param[])
        every writes(__ErrorOutFile, !param)
        write(__ErrorOutFile)
        stop(__ErrorOutFile, "Error in ", Caller(), ".")
    end
    
    method PrintMessage(param[])
        every writes(__ErrorOutFile, !param)
        write(__ErrorOutFile)
        write(__ErrorOutFile, "Error in ", Caller() , ".")
    end
    
    method Caller()
        local pc, cc, mc, parc
        pc := ProcedureCalling(3)
        cc := ClassCalling(3)
        mc := MethodCalling(3)
        parc := ParamCalling(3)
        return (("procedure " || \pc) | "method " || cc || "." || mc) || parc
    end
    
    method ProcedureCalling(level)
        local name, res
        image(proc(&current, \level | 1)) ? {="procedure "; name := tab(0) }
        res := CallingComponents(name)
        return \res[1]
    end
   
    method ClassCalling(level)
        local name, res
        image(proc(&current, \level | 1)) ? {="procedure "; name := tab(0) }
        res := CallingComponents(name)
        return \res[2]
    end

    method MethodCalling(level)
        local name, res
        image(proc(&current, \level | 1)) ? {="procedure "; name := tab(0) }
        res := CallingComponents(name)
        return \res[3]
    end
    
    method ParamCalling(level)
        local name
        name := "("
        /level := 1
        every name ||:= paramnames((proc(&current, level))) || ","
        name[-1] := (name[-1] == "," & "")
        name[2:7] := (name[2:7] == "self," & "")
        name ||:= ")"
        return name
    end

    method CallingComponents(name)
        local nameproc, nameclass, namemethod, i
        name ? { 
            i := find("_")
            if \i then {
                nameclass := tab(i)
                move(1)
                namemethod := tab(0)
            } else
                nameproc := name
        }
        return [nameproc, nameclass, namemethod]
    end
    
    method Debug(mode)
        __DebugMode := mode
    end
    
    method DebugMode()
        if \__DebugMode then
            return __DebugMode
        else 
            return fail
    end
    
    method ErrorOut(errorfile, writeappend)
        static type
        initial {
            type := proc("type", 0)
        }
        /errorfile := &errout
        if \__ErrorOutFile then
            close(__ErrorOutFile)
        if type(errorfile) == "string" then {
            /writeappend := "w"
            if type(writeappend) == "string" then 
                __ErrorOutFile := open(errorfile, (("w" | "a") == writeappend) 
| "w")
            else
                __ErrorOutFile := open(errorfile, "w")
        } else if type(errorfile) == "file" then
                __ErrorOutFile := errorfile
            else
                __ErrorOutFile := &errout
    end
    
initially(errorfile, writeappend)
    static type
    initial {
        type := proc("type", 0)
    }
    ErrorOut(errorfile, writeappend)
    Error := self
end
link classobject

procedure main()
    local a, b
    writeln("Initialisation of class A")
    A()
    writeln("create a new object of hidden class _A associated with A")
    a := A.New("aaaa")
    writeln("a: ", ximage(a))
    writeln("a.A(): ", a.A())
    writeln("setting a to new A() value")
    a.SetA("bbba")
    writeln("a.A(): ", a.A())
    writeln("A.A(a): ", A.Aa(a))
    writeln("Set a new value to a")
    A.SetA(a, "abbb")
    writeln("a.A(): ", a.A())
    writeln("IsObjectOf(a, \"A\")", IsObjectOf(a, "A"))
    writeln("create a DeepCopy of a and assign to b")
    b := DeepCopy(a)
    writeln("a: ", ximage(a))
    writeln("b: ", ximage(b))
    writeln("update b")
    b.SetA("xxxx")
    writeln("a: ", ximage(a))
    writeln("b: ", ximage(b))
    writeln("a.A(): ", a.A())
    writeln("b.A(): ", b.A())
    writeln("IsObjectOf(b, \"A\")", IsObjectOf(b, "A"))
    every writeln("Properties of A: ", ximage(ObjectProperties(A)))
    every writeln("Properties of A: ", ximage(ObjectProperties("A")))
    writeln("Superclass of a:", ximage(SuperClass(a)))
    writeln("Is A already run:", AlreadyRun(A))
end

class __A : ClassObject(_a)

    method A()
        return _a
    end
    
    method SetA(a)
        _a := a
    end
    
initially(a)
    _a := a
end

class A : ClassClass()
    
    method A(a)
        return a.A()
    end
    
    method SetA(a, aa)
        a.SetA(aa)
    end
    
initially()
    if not AlreadyRun(A) then {
        writeln("Initialisation of A started")
        SetClass(__A)
        self.ClassClass.initially()
        A := self
    }
end

procedure writeln(l[])
    static fout
    initial {
        fout := open("testClassObject.output", "w")
    }
    push(l, fout)
    write ! l
end
------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Unicon-group mailing list
Unicon-group@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to