← Back to team overview

ooc-dev team mailing list archive

Re: issue with properties?

 

Hey Alec,

I thought this would work, but then I realized that it resulted in an
infinite recursion. Since normalize assigns to numerator and denominator,
this invokes the property setter which in turn runs normalize().

Yep, you're right about that. You could work around it by normalizing the fraction *inside* the setter (because writing accesses won't get replaced by setter calls here), but that would lead to code duplication, and we hate code duplication. :p

Another working solution is: Make `numerator` and `denominator` *virtual* properties that work with an (private-by-convention) attribute. Like this:

    Fraction : class {

        _numerator: Int
        numerator: Int {
            get {
                _numerator
            }
            set(n) {
                _numerator = n
                normalize()
            }
        }

        _denominator: Int
        denominator: Int {
            get {
                _denominator
            }
            set(d) {
                if(d != 0) {
                    _denominator = d
                    normalize()
                }
            }
        }

        init: func (=numerator, =denominator) {}

        normalize: func {
            "normalize()" println()
            gcd := this gcd()
            if(gcd != 0) {
                _numerator /= gcd
                _denominator /= gcd
            }
        }

        gcd: func -> Int {
            (a,b) := (this _numerator, this _denominator)
            while(b != 0) {
                t := b
                b = a % b
                a = t
            }
            a
        }
    }

    main: func {
      f := Fraction new(4, 5)
      f denominator = 8
      "%d/%d" printfln(f numerator, f denominator)
    }

`normalize` manipulates `_numerator`/`_denominator` here - they aren't properties, so they don't cause recursion.

Well okay, it still *looks* like a workaround, but i think it isn't - it would be done similarly in Python, for example. The advantage of our current approach (allow direct access only inside the getter/setter) is: We can do virtual properties: Properties that don't have a real value in the object struct. This is useful for wrapping C getter/setter functions to cover properties.

Hope that helps,

Friedrich



Follow ups

References