Skip to content

Latest commit

 

History

History
140 lines (110 loc) · 3.96 KB

README.md

File metadata and controls

140 lines (110 loc) · 3.96 KB

ObjectOriented

Stable Dev Build Status

ObjectOriented.jl is a mechanical OOP programming library for Julia. The design is mainly based on CPython OOP but adapted for Julia.

The supported features:

  • multiple inheritances
  • using dot operators to access members
  • default field values
  • overloaded constructors and methods
  • Python-style properties (getters and setters)
  • generics for the OOP system
  • interfaces

Check out our documentation.

We recommend you to read How to Translate OOP into Idiomatic Julia before using this package. If you understand your complaints about Julia's lack of OOP come from your refutation of the Julia coding style, feel free to use this.

For people who want to use this package in a more Julian way, you can avoid defining methods (and Python-style properties) with @oodef.

Preview

@oodef mutable struct MyClass <: MySuperClass
    a::Int
    b::Int

    function new(a::Integer, b::Integer)
        self = @mk
        self.a = a
        self.b = b
        return self
    end

    function compute_a_plus_b(self)
        self.a + self.b
    end
end

julia> inst = MyClass(1, 2)
julia> inst.compute_a_plus_b()
3

A more concise rewrite using @mk is:

@oodef mutable struct MyClass <: MySuperClass
    a::Int
    b::Int

    function new(a::Integer, b::Integer)
        @mk begin
            a = a
            b = b
        end
    end

    function compute_a_plus_b(self)
        self.a + self.b
    end
end

julia> inst = MyClass(1, 2)
julia> inst.compute_a_plus_b()
3

Hints For Professional Julia Programmers

As the dot method (self.method()) is purely a syntactic sugar thing, using the idiomatic Julia code like method(self) is usually better. Using the idiomatic Julia methods, method ambiguity can be avoided, which is of course better than OOP in this case.

You can avoid defining dot methods as shown below:

@oodef struct MyType
    field1::Int
    field2::Int
    function new(a, b)
        @mk begin
            field1=a
            field2=b
        end
    end

    #= not Julian:
    function some_func(self)
       return self.field1 + self.field2
    end
    =#
end

# Julian way:
function some_func(self :: @like(MyType)) # @like(...) accepts subtypes
    self.field1 + self.field2
end

@oodef struct MyDerivedType <: MyType
    c::Int
    function new(a, b, c)
        @mk begin
            MyType(a, b)
            c = c
        end
    end
end

some_func(MyType(1, 2)) # 3
some_func(MyDerivedType(1, 2, 3)) # 3

Troubleshooting

  1. The integrated debugger implemented in Julia-VSCode cannot handle @generated functions, which causes a bug when entering @mk expressions. A workaround can be made as follows:

    @oodef mutable struct YourClass
         x::Int
         y::Int
         function new(x, y)
             # you can debug here
             self = @mk begin
                 # you can debug here
                 x = x
                 # you can debug here
                 y = y
                 # do not reach here!
                 # please jump over the end of '@mk' expression!
             end
             # you can debug here
             return self
         end
    end