Sederhanakan integrasi paket Julia dengan ekstensi – Beragampengetahuan
Oleh: Konsultasi Great Lakes
Diposting ulang dari:
Postingan ini ditulis oleh Steven Whitaker.
Bahasa pemrograman Julia adalah bahasa tingkat tinggi yang dikenal, setidaknya sebagian, karena kemampuan komposisinya yang luar biasa. Sebagian besar komposisi Julia berasal dari beberapa pengirimannya, yang memungkinkan fungsi yang ditulis dalam satu paket berfungsi dengan objek dari paket lain tanpa salah satu paket bergantung atau bahkan mengetahui paket lainnya. (Lihat posting blog lain untuk lebih jelasnya.)
Namun, terkadang berguna bagi sebuah paket untuk dapat memperluas fungsinya untuk menyediakan fungsionalitas tambahan ketika diberikan objek bertipe tertentu dari paket lain. Salah satu cara untuk melakukannya adalah dengan menambahkan paket lain sebagai dependensi eksplisit sehingga tipenya tersedia untuk digunakan paket pertama guna mendefinisikan metode khusus untuk paket tersebut.
Namun bagaimana jika paket tersebut dapat berfungsi normal tanpa fungsi tambahan? Bagaimana jika fungsionalitas tambahan merupakan bagian integral dari fungsionalitas paket dan hanya berlaku jika pengguna ingin bekerja dengan objek jenis tertentu? Dalam hal ini, tidak masuk akal untuk menjadikan paket lain sebagai ketergantungan langsung, karena itu semua pengguna membayar harga dalam waktu pemuatan paket tambahan untuk mendapatkan fungsionalitas yang hanya diinginkan oleh sebagian pengguna.
Solusinya adalah ekstensi paket. Ekstensi paket adalah kode yang dimuat bersyarattergantung pada paket lain apa yang telah dimuat secara eksplisit oleh pengguna. Dengan kata lain, ketika pengguna memuat paket dan dependensi yang menjadi sandaran ekstensi, ekstensi tersebut akan dimuat secara otomatis. Dengan cara ini, pengguna yang ingin menggunakan paket dapat melakukannya tanpa menambahkan dependensi, sementara pengguna yang menginginkan fungsionalitas tambahan dapat memuat sendiri dependensinya.
Pada postingan kali ini kita akan mempelajari beberapa ekstensi paket yang ada di ekosistem paket Julia. Kita juga akan mempelajari cara menulis ekstensi paket dan cara memuat ekstensi.
Posting ini mengasumsikan bahwa Anda sudah familiar dengan struktur paket Julia. Jika Anda perlu mempelajari lebih lanjut, lihat postingan kami tentang cara membuat paket Julia.
- ForwardDiff.jl memiliki ekstensi ke StaticArrays.jl, memungkinkan diferensiasi otomatis dalam mode maju dengan keunggulan kinerja StaticArrays.
- Lux.jl memiliki ekstensi ke Flux.jl yang menambahkan fungsionalitas untuk mengonversi model pembelajaran mendalam yang ditentukan di Flux ke Lux.
- Beberapa paket lain memiliki ekstensi (lihat saja
extdirektori repositori git ini):
Untuk membuat ekstensi paket, kita perlu membuat modul yang menambahkan definisi metode ke fungsi dari salah satu paket (paket yang sedang diperluas atau paket yang memicu pemuatan ekstensi) yang mengirimkan tipe dari paket lainnya. Modul ini akan ada di ext Direktori paket sedang diperluas. Selain itu, paket ekspansi Project.tomlperlu diperbarui untuk memberi tahu manajer paket tentang keberadaan ekstensi dan kapan memuatnya.
Mari kita lihat contoh spesifiknya.
Contents
Contoh paket untuk ekstensi
Contoh ini akan dibuat pada paket khusus bernama Averages.jl, yang telah kita bahas di postingan blog tentang pengujian paket Julia. Kode paketnya adalah sebagai berikut:
module Averagesusing Statistics: meanexport compute_averagecompute_average(x) = (check_real(x); mean(x))function compute_average(a, b...) check_real(a) N = length(a) for (i, x) in enumerate(b) check_real(x) check_length(i + 1, x, N) end T = float(promote_type(eltype(a), eltype.(b)...)) average = VectorT(undef, N) average .= a for x in b average .+= x end average ./= length(b) + 1 return a isa Real ? average[1] : averageendfunction check_real(x) T = eltype(x) T <: Real || throw(ArgumentError("only real numbers are supported; unsupported type $T"))endfunction check_length(i, x, expected) N = length(x) N == expected || throw(DimensionMismatch("the length of input $i does not match the length of the first input: $N != $expected"))endend
Buat ekstensi
Dalam contoh ini, kami akan membuat ekstensi yang mengimplementasikan fungsionalitas tambahan DataFrames.Ini adalah tugas yang perlu kita lakukan untuk menerapkan ekstensi:
-
Buat ekstensi
Averages/ext/AveragesDataFramesExt.jl.Perhatikan bahwa ini mengikuti konvensi penamaan untuk ekstensi:<PackageName><NameOfPackageThatTriggersExtension>Ext.Di dalam file ini kita membuat modul bernamaAveragesDataFramesExt(nama yang sama dengan file) dan masukkan kode yang ingin kita sertakan ketika Averages.jl dan DataFrames.jl dimuat bersama:module AveragesDataFramesExtimport Averagesusing Averages: compute_averageusing DataFrames: All, DataFrame, combinefunction Averages.compute_average(df::DataFrame) @info "Running code in AveragesDataFramesExt!" df_avg = combine(df, All() .=> compute_average) return df_avgendend -
Menambahkan
[weakdeps]Dan[extensions]bagian keProject.tomloleh Rata-rata.jl. (Lihat posting blog kami sebelumnya untuk informasi asliProject.toml.)DI DALAM[weakdeps]tentukan DataFrames.jl dan UUID-nya, dan, di[extensions]tentukan ekstensi kami (AveragesDataFramesExt) dan ketergantungannya (DataFrames.jl). UUID DataFrames.jl dapat ditemukan di DataFrames.jlProject.toml.Ini adalah pembaruannya
Project.tomluntuk rata-rata.jl:name = "Averages"uuid = "1fc6e63b-fe0f-463a-8652-42f2a29b8cc6"version = "0.1.0"[deps]Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"[weakdeps]DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"[extensions]AveragesDataFramesExt = "DataFrames"[extras]Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"[targets]test = ["Test"](Perhatikan bahwa, seperti versi yang kompatibel
[deps]Paket dapat ditentukan menjadi satu[compat]Bagian ini, versi yang kompatibel[weakdeps]paket yang ditentukan.)
Gunakan ekstensi
Pertama, mari kita lihat apa yang terjadi jika kita mencobanya tanpa ekstensi:
julia> compute_average(DataFrame(a = [1, 2], b = [3.0, 4.0]))ERROR: ArgumentError: only real numbers are supported; unsupported type AnyStacktrace: [1] check_real(x::DataFrame) @ Averages /path/to/Averages/src/Averages.jl:34 [2] compute_average(x::DataFrame) @ Averages /path/to/Averages/src/Averages.jl:7 [3] top-level scope @ REPL[5]:1
Jadi sekarang mari kita lihat apakah ekstensi memungkinkan pemanggilan fungsi ini berfungsi.
Untuk menggunakan ekstensi, instal dan muat Rata-rata.jl dan DataFrames.jl (untuk Rata-rata.jl, gunakan dev perintah, yaitu pkg> dev /path/to/Averages) lalu telepon compute_average:
Julia> menggunakan Rata-rata, DataFramesjulia> hitung_rata-rata(DataFrame(a = [1, 2]b = [3.0, 4.0]))[ Info: Running code in AveragesDataFramesExt!12 DataFrame Row a_compute_average b_compute_average Float64 Float64 1 1.5 3.5
Nice, it works!And with that,we have an example package extensionthat illustrates how to implement your own.
And remember,a user of Averages.jlwill only incur the cost of loading AveragesDataFramesExtif they load DataFrames.jl.For more details,see the slide annotationsin this screenshot from JuliaCon 2023:

(See also the full talk on package extensionsfor even more details.)
Note: Where Should an Extension Live?
By the way,if you’re wondering why we put the extension in Averages.jlinstead of DataFrames.jl,the answer isthat it doesn’t really matterbecause the user experiencewill be the same regardless.If you still want some rules to follow,I’m not aware of any Julia best-practicesin this regard,but here are some rules that make sense to me:
- If one of the two packages in questiondefines an interface,the extension should go in the packagethat implements the interface.
- Otherwise,put the extension in the packagethat owns the functionsthat are being extended.In our example,we extended the
compute_averagefunction.Since this function is defined in Averages.jl,we put the extension in Averages.jl. - An exception to the previous ruleis if getting the new functionality rightrequires a good understandingof the internals of the new data typethat’s being dispatched on,in which case the extensionshould belong in the packagethat defines the type.For example,if
compute_averagewas super complicatedfor some reasonwhen working withDataFrames,it would make sense for those with the needed expertise(i.e., the developers of DataFrames.jl)to own and maintain the extension.
In this post,we listed some real Julia packagesthat have their own package extensions.We also demonstrated creating our own extensionfor an example packageand showed how to use the extension’s code.
What package extensions have you found useful?Let us know in the comments below!
]]>
Terkait
Software Terbaru Saat Ini
Aplikasi yang sedang trend saat ini
object oriented programming, programming language, programming adalah, web programming, belajar programming, tournament software, software, software adalah, contoh software, apa itu software, pengertian software, aplikasi, aplikasi penghasil uang, aplikasi bokep, aplikasi video, programming
#Sederhanakan #integrasi #paket #Julia #dengan #ekstensi