• Tidak ada hasil yang ditemukan

Hasil Ganda / Multiple Results

BAB 5 FUNGSI-FUNGS

5. Fungsi-Fungs

5.1 Hasil Ganda / Multiple Results

Satu diluar kebiasaan, tetapi merupakan fitur menyenangkan dari Lua adalah bahwa fungsi- fungsi dapat mengembalikan hasil-hasil ganda(multiple results). Beberapa fungsi yang sudah didefinisikan di Lua mengembalikan nilai-nilai ganda. Satu contoh adalah fungsi string.find, yang menempatkan suatu pola di suatu string. Yang menghasilkan dua indeks : indeks dari karakter dimana pola yang sesuai dimulai dan lainnya saat berakhir (atau nil jika itu tidak dapat menemukan pola). Suatu penugasan ganda mengizinkan program itu untuk mendapat kedua hasil tersebut:

s, e = string.find("hello Lua users", "Lua")

print(s, e) --> 7 9

Fungsi-fungsi yang ditulis dalam Lua juga dapat mengembalikan hasil-hasil ganda, dengan mendaftarkan mereka semua setelah kata kunci return. Sebagai contoh, suatu fungsi untuk menemukan unsur maksimum dalam array dapat mengembalikan nilai maksimum dan lokasinya:

function maximum (a)

local mi = 1 -- maximum index local m = a[mi] -- maximum value for i,val in ipairs(a) do

if val > m then mi = i m = val end end return m, mi end print(maximum({8,10,23,12,5})) --> 23 3

Lua selalu menyesuaikan sejumlah hasil dari suatu fungsi ke keadaan dari suatu panggilan. Ketika kita memanggil suatu fungsi sebagai statemen, Lua membuang semua hasil. Ketika kita menggunakan suatu panggilan sebagai satu ekspresi, Lua hanya menyimpan hasil yang pertama. Kita mendapat semua hasil hanya ketika panggilan itu terakhir (atau satu-satunya) ekspresi di dalam daftar ekspresi-ekspresi. Daftar ini muncul dalam empat konstruksi di Lua: penugasan ganda, argumentasi-argumentasi untuk fungsi pemanggilan, table konstruktor, dan statemen-statemen

return. Untuk menggambarkan semua penggunaan ini, kita akan mengasumsikan definisi-definisi berikut untuk contoh-contoh yang berikutnya:

function foo0 () end -- returns no results function foo1 () return 'a' end -- returns 1 result function foo2 () return 'a','b' end -- returns 2 results

Dalam penugasan ganda, suatu fungsi pemanggil sebagai (atau hanya) ekspresi terakhir yang menghasilkan banyak hasil yang dibutuhkan untuk memenuhi variabel-variabel:

x,y = foo2() -- x='a', y='b'

x = foo2() -- x='a', 'b' is discarded x,y,z = 10,foo2() -- x=10, y='a', z='b'

Jika suatu fungsi tidak memiliki hasil-hasil, atau bukan sebagai hasil-hasil yang kita inginkan, Lua menghasilkan nil-nil:

x,y = foo0() -- x=nil, y=nil x,y = foo1() -- x='a', y=nil

x,y,z = foo2() -- x='a', y='b', z=nil

Suatu fungsi pemanggil yang bukan elemen terakhir dalam daftar selalu menghasilkan satu hasil :

x,y = foo2(), 20 -- x='a', y=20

x,y = foo0(), 20, 30 -- x='nil', y=20, 30 diabaikan

Ketika suatu fungsi pemanggil adalah yang terakhir (atau satu-satunya) argumentasi ke

panggilan yang lain, semua hasil dari panggilan pertama menjadi sebagai argumentasi-argumentasi. Kita sudah melihat contoh-contoh dari konstruksi, dengan cetakan:

print(foo1()) --> a print(foo2()) --> a b print(foo2(), 1) --> a 1

print(foo2() .. "x") --> ax (see below)

Ketika panggilan ke foo2 muncul dalam satu ekspresi, Lua menyesuaikan sejumlah hasil

pada 1; maka, di baris terakhir, hanya "a" yang digunakan dalam penggabungan.

Fungsi print dapat menerima variabel number dari argumentasi-argumentasi. (Di dalam bagian yang berikutnya, kita akan lihat bagaimana caranya menulis fungsi-fungsi dengan nomor variabel dari argumentasi-argumentasi.) Jika kita menulis f(g()) dan f punya suatu nomor yang ditetapkan/diperbaiki dari argumentasi-argumentasi, Lua menyesuaian sejumlah hasil- hasil dari g sebanyak parameter-parameter dari f, ketika kita lihat sebelumnya.

Suatu konstruktor juga mengumpulkan semua hasil pemanggilan, tanpa penyesuaian- penyesuaian:

a = {foo0()} -- a = {} (table kosong) a = {foo1()} -- a = {'a'}

a = {foo2()} -- a = {'a', 'b'}

Seperti biasa, perilaku ini terjadi hanya ketika panggilan itu adalah terakhir pada daftar; jika tidak, setiap panggilan menghasilkan persisnya satu hasil:

a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4

Akhirnya, suatu statemen seperti return f() mengembalikan semua nilai-nilai yang dikembalikan oleh f:

function foo (i)

if i == 0 then return foo0() elseif i == 1 then return foo1() elseif i == 2 then return foo2() end

end

print(foo(1)) --> a print(foo(2)) --> a b

print(foo(0)) -- (no results) print(foo(3)) -- (no results)

Anda dapat memaksa suatu panggilan untuk mengembalikan persisnya satu hasil dengan menyertakannya dalam satu pasang tanda kurung tambahan:

print((foo0())) --> nil print((foo1())) --> a print((foo2())) --> a

Hati-hati bahwa suatu statemen return tidak memerlukan tanda kurung disekitar nilai

yang dikembalikan, maka setiap pasang tanda kurung ditempatkan disana dihitung sebagai satu pasangan tambahan. Hal itu ,suatu statemen seperti return (f()) selalu kembalikan satu nilai

tunggal, tak peduli berapa banyak nilai-nilai f kembali. Barangkali ini adalah apa yang anda inginkan, mungkin juga tidak.

Suatu fungsi khusus dengan pengembalian ganda adalah unpack. Yang menerima satu array dan mengembalikan sebagai hasil-hasil semua unsur-unsur dari array, mulai dari indeks 1:

print(unpack{10,20,30}) --> 10 20 30 a,b = unpack{10,20,30} -- a=10, b=20, 30 diabaikan

Satu penggunaan penting untuk membongkar/unpack adalah pada mekanisme generic

call(pemanggilan umum). Suatu mekanisme generic call mengizinkan anda untuk memanggil setiap fungsi, dengan setiap argumentasi-argumentasi, secara dinamis. Di C ANSI, sebagai contoh, sama sekali tidak mungkin untuk melakukan itu. Anda dapat mendeklarasikan suatu fungsi yang menerima suatu nomor variabel dari argumentasi-argumentasi (dengan stdarg.h) dan anda dapat memanggil suatu fungsi variabel, menggunakan penunjuk/pointer ke fungsi-fungsi. Bagaimanapun, anda tidak bisa memanggil suatu fungsi dengan suatu nomor variabel dari argumentasi-argumentasi: Setiap panggilan yang anda tulis di C telah memiliki bilangan tetap dari argumentasi-argumentasi dan masing-masing argumentasi punya tipe jenis yang ditetapkan. Di Lua, jika anda ingin memanggil suatu variable fungsi f dengan variabel argumentasi-argumentasi dalam satu array a, anda hanya menulis

f(unpack(a))

Panggilan itu untuk membongkar/unpack hasil-hasil semua nilai-nilai di a, yang menjadi

argumentasi-argumentasi untuk f. Sebagai contoh, jika kita mengeksekusi

f = string.find a = {"hello", "ll"}

Lalu panggilan f(unpack(a)) menghasilkan 3 dan 4, tepat sama saat panggilan statis

string.find("hello", "ll").

Meski pendefinisian telah di bongkar/unpack ditulis dalam C, kita dapat menulisnya juga di Lua, menggunakan pengulangan:

function unpack (t, i) i = i or 1

if t[i] then

return t[i], unpack(t, i + 1) end

end

Pertama kali kita memanggilnya, dengan suatu argumentasi tunggal, i mendapat 1. Lalu fungsi mengembalikan t[1] diikuti oleh semua hasil dari unpack(t, 2), yang pada gilirannya mengembalikan t[2] yang yang diikuti oleh semua hasil dari unpack(t, 3), dan seterusnya, sampai unsur tidak nol terakhir.