#!/usr/bin/ruby

# In Sidef, the modules are global namespaces which can incorporate one or more statements, such as functions,
# which can be accessed later by using the module's name followed by a pair of colons and the name of the function.

#
## Module + func
#
module Fibonacci {
    func nth(n) {
        n > 1 ? (nth(n-2) + nth(n-1)) : n;
    }
}

Fibonacci::nth(5) == 5 || "Fib error!".die;


#
## Module + static var + func
#
module Google::Chrome {
    static version = 41;
    func info {
        return "Developed by Google inc.";
    }
}

Google::Chrome::version += 1;
Google::Chrome::version == 42 || "Version error!".die;

Google::Chrome::info().contains("Google") || "Info error!".die;


#
## Module + (class + method)
#
module Foo {
    class Bar {
        method Zoe {
            return "All good!";
        }
    }
}

Foo::Bar().Zoe == "All good!" || "module+class error!".die;


#
## Class + (module + func + func) + method
#
class Test {
    module Foo {            # module redeclaration
        func Bingo {
            return "Bingo!";
        };
        func Yay {
            return "Yay!";
        };
    };

    method Bar {
        Foo::Bingo() == "Bingo!" || "method call error!".die;
    };
}

Test().Bar;
Foo::Bingo() == "Bingo!" || "Bingo error!".die;
Foo::Yay()   == "Yay!"   || "Yay error!".die;


#
## Module + (module + func) + func
#
module Hi {
    module Hello {
        func hello {
            "Hello";
        }
    };
    func hi {
        Hello::hello() == "Hello" || "Inner hello error!".die;
        "Hi";
    };
}

Hi::hi()           == "Hi"    || "Hi error!".die;
Hello::hello() == "Hello" || "Hello error!".die;


###################
say "** Test passed!";
###################