「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。今月(2022年10月)からは多忙につき、日々の投稿数を減らします。

MENU

Juliaを基礎からゆっくりと(その08/X)

 \mathrm{R}\mathrm{Python}\mathrm{C}言語関係など覚えたいもの、覚えるべきものはたくさんある一方で、注目が集まっているから、やってみたい。ということでプログラミング言語としての\mathrm{Julia}を学んでいく。

2. Juliaの言語機能

2.7 モジュール

 ソースコードの名前が衝突することを防ぐのに、名前空間を用いる。\mathrm{Julia}のパッケージはそれぞれが名前空間を持つ。

2.7.1 モジュールの機能

 \mathrm{Julia}には、名前空間として機能するモジュールというオブジェクトがある。あるモジュールの名前空間に所属する名前は、モジュール名を通じて参照する。
 \mathrm{Julia}のコードは、常にモジュールに関連づいた名前空間の中で実行される。現在の実行位置でどのモジュールが有効になっているかは@__\mathrm{MODULE}__マクロで確認できる。

@__MODULE__
2.7.3 既存モジュールの利用

 既存モジュールを利用するには、\mathrm{using}文を用いるのが一般的である。
 \mathrm{using}文は特定の名前を指定してそれのみ読み込むこともできる。そのときには\mathrm{using}:(コロンを付記)の後に取り込みたい関数を記載する。
 \mathrm{using}文は特定の名前を指定しないと、暗黙的に意図しないものが読み込まれる恐れがある。そのため、暗黙的に名前を読み込まない\mathrm{import}文を用いることも一考の余地がある。

using Statistics

mean([1,2,3])

std(1,2,3)


2.7.4 新しいモジュールの定義

 モジュールを新たに定義することもできる。\mathrm{module}キーワードと\mathrm{end}キーワードでモジュールのコードを挟む。このとき、慣例で両キーワードに挟まれたモジュールのコードにはインデントを入れない。

# module (モジュール名)
# …
# モジュールのコード
# …
# end
module Greeting
hello(name) = println("Hello, $(name)")
end

Greeting.hello("Julia")

# モジュールの定義は入れ子にできる
# モジュールの定義は入れ子にできる
module A
    hello(name) = println("Good morning, $(name)")
    module B1 # A.B1モジュール
        hello(name) = println("Hi, $(name)")
    end
    module B2 # A.B2モジュール
        hello(name) = println("Good evening, $(name)")
    end
end

# using文やimport文で指定されたモジュール名は、LOAD_PATH変数に収められたプロジェクト・パスから検索される
### module文で定義されたモジュールはそこに無いため、エラーを起こす。
### そこで.を付けて相対パスで指定する
using A
A.hello("Julia")

using .A
A.hello("Julia")

using .A
A.B1.hello("Julia")

2.7.5 ファイルの分割

 モジュールのソースコードが長すぎる場合には可読性が落ちるため、適度に分割して別ファイルにすることも検討すべきである。\mathrm{Julia}では\mathrm{include}関数を用いてモジュールを複数のファイルに分けて定義できる。このとき\mathrm{include}関数で読み込ませるソースコードはフォルダ管理の都合で相対パスで指定するのが普通である。

# 以下のように用いる
module foo
include("file1.jl")
include("file2.jl")
include("file3.jl")
end
2.7.6 他モジュールで定義された関数の拡張

 \mathrm{Julia}は多重ディスパッチを中心としたプログラミング言語であり、あるモジュールで定義された関数をその外から拡張する機能を持つ。これにより、演算子を自分で定義したデータ型にも適用できるように拡張したり、\mathrm{for}文で用いられるイテレータを実装したりできる。

# 他モジュールの関数の拡張
### 自分で定義したvec3型に対してlength関数を呼び出せるように拡張する

struct vec3{T} <: AbstractVector{T}
    x::T
    y::T
    z::T
end

import Base:length

length(v::vec3) = 3
プライバシーポリシー お問い合わせ