1.1
1.2
1.3
1.3.1
1.3.2
1.3.3
1.3.4
1.4
1.4.1
1.4.2
1.4.3
1.4.4
1.4.5
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.6
1.6.1
1.6.2
1.6.3
1.6.4
1.6.5
1.6.6
1.6.7
1.6.8
1.7
1.7.1
1.7.2
1.7.3
1.7.4
TableofContentsGiriş
İnceleme
Bölüm1
RubyHakkında
Kurulum
İnteraktifKullanım
RubyKomutuveParametreleri
Bölüm2
Syntax(SözDizimi)veRezerveKelimeler
Değişkenler
ÖnTanımlıvePseudo(GerçekOlmayan)Değişkenler
Operatörler
GlobalConstants(GenelSabitler)
Bölüm3
Methods(Fonksiyonlar)
Blocks(Bloklar)
ProcveLambda
ConditionalStatements(Koşullar)
Bölüm4
Object
Number
String
Array
Hash
Symbol
Class
Module
Bölüm5
EnumerationveIteration
Ranges
FileSystemveIO(DosyaSistemi)
ExceptionHandling
2
1.7.5
1.8
1.8.1
1.8.2
1.8.3
1.8.4
1.8.5
1.8.6
1.8.7
1.9
1.10
1.10.1
1.10.2
1.10.3
1.10.4
1.11
KernelModülü
Bölüm6
MonkeyPatching
RegularExpressions
TimeveDateNesneleri
RubyPaketleri:RubyGems
PaketYöneticisi:Bundler
KomutSatırı(Command-Line)Kullanımı
MetaProgramming
KodYazmaTarzı(StyleGuide)
GerçekHayatRubyÖrnekleri
NedenRuby?
RubyveTDD/BDD/CI
KendiRubygem'imiziyapalım!
SinatraveWeb
YazarHakkında
3
Ruby101Kitabı
ÖnsözKitapyazmakhephayalinikurduğumbirşeydi.Hemkendiişimeyarayacakhemdebaşkalarınınişinigörecekbirkitapolmalıydı.Aslındabirseneöncebuişesoyundumamabirtürlüfırsatbulamadım.
Kafamdakabacaplanlaryaptımhepamasonnoktayıbirtürlükoyamadım.Gitbook.iobukonudaçokişimeyaradı.HembenifişekledihemdeGitHubilekolayentegreolmasıkendimiorganizeetmemaçısındançokrahatoldu.
HepO'Reilly'ninPocketyanicepkitaplarınabayılmışımdır.Hemboyutitibariylehemdeiçerikanlamında.Sürekliyanınızdataşıyabileceğiniz,içindekonusuylailgiliherşeyinkompakbirşekildebulunduğukaynak.
Amacım,bukitaplartadında,herzamanyanınızdabulunabilecek,tabiricaizsebaşucukitabıhazırlamak.
Kitabıhazırlarkenençokzorlandığımkısımİngilizce'denanlamlıTürkçemetinlerçıkartmakoldu.Bazışeyleriİngilizceolarakifadeetmekçokkolay,fakatbazıdurumlardatamTürkçeanlamlıkarşılıkbulmakgerçektenzoroluyor.
PrensipolarakDeveloper(YazılımGeliştirenKişi)deneninsanındefaultolarakİngilizcebilmesigerektiğineinanıyorum.Neden?Örneğinmilyonlarcaaçık-kaynakprojeninbulunduğuGitHub'daherkesİngilizcekonuşuyor.
Takıldığınızbirkonuda,GitHub'dayorumlarıokumanızgerekecek.Hattabazensizbirşeysoracaksınız.Issue'larabakacaksınız,PullRequestyapacaksınız.Gördüğünüzgibibircümledeikitaneİngilizceterim.Bunlarevrensel.Bilmemizgerekiyoryoksaçuvallarız:)
Özelliklepekçokşeyiolduğugibiİngilizceolarakkullanmakistedim.TabiikiTürkçeanlamınıdayazdımfakat,genelolarakkullandığımterminolojiRubyveyazılımgeliştirmeterminolojisi.
ÖrneğinConstantdediğimdebununneanlamageldiğinianlamışolmanızgerekiyor.YadaInstancedediğimde,bununsınıftanoluşturulmuşbirnesneolduğunuanlamanızgerekiyor.
Yazılımdünyasıneyazıkkiİngilizcevetümkaynaklardaİngilizce.Bubakımdanorijinalkelimeleriveterminolojiyiöğrenmemiz,bilmemizşart:)
Giriş
4
LisansMevzusuPrensipolarak,GitHub'aPublicolarakkoyduğumherşey,herkestarafındanhertürlüşekildekullanılabilir.BencePublicolaraksürülenbirşey(kibeneskiAmiga'cıPublicDomain'cibiriyim)herkesintepetepekullanabilmesiamaçlıolmalıdır.
Hertürlülisansolayınakarşıyım.Eğerbirtürlisanslamayapacaksanızkendinizesaklayın:)
Bukitapananızınaksütügibihepinizehelalolsun.Umarımişinizeyarar!
Kitabıonlineolarakokumakiçin:
https://vigo.gitbooks.io/ruby-101/content/
TamamlanmaDurumu(%78)
Bölüm1(%94)
RubyHakkındaKurulumİnteraktifKullanımRubyKomutuveParametreleri(%98)
Bölüm2(%100)
Syntax(SözDizimi)veRezerveKelimelerDeğişkenlerÖnTanımlıvePseudo(GerçekOlmayan)DeğişkenlerOperatörlerGlobalConstants(GenelSabitler)
Bölüm3(%100)
Methods(Fonksiyonlar)Blocks(Bloklar)ProcveLambdaConditionalStatements(Koşullar)
Bölüm4(%100)
ObjectNumberStringArray
Giriş
5
HashSymbolClassveModule
Bölüm5(%58)
EnumerationveIterationRangesFileSystemveIO(DosyaSistemi)(%90)ExceptionHandling(--)KernelModülü(--)
Bölüm6(%50)
MonkeyPatchingRegularExpressions(--)TimeveDateNesneleri(%50)RubyPaketleri:RubyGemsPaketYöneticisi:Bundler(--)KomutSatırı(Command-Line)Kullanımı(--)MetaProgramming
KodYazmaTarzı(StyleGuide)(%98)
DeğişkenTanımlamalarıBlokTanımlamalarıSyntaxTanımlamalarıSemantikTanımlamalarYanlışveDoğruKullanımlarİsimlendirmeler
GerçekHayatRubyÖrnekleri(%25)
NedenRuby?RubyveTDD/BDD/CI(--)KendiRubygem'imiziyapalım!(--)SinatraveWeb(--)
Giriş
6
İncelemeBukısımaTechnicalReviewgelecek...
İnceleme
7
Bölüm1BubölümdeRuby'ninkısacatarihçesinebakacağız.BunaekolarakfarklıişletimsistemlerindeRubykurulumunakısacadeğineceğiz.EğerOSXyadaLinuxtüreviişletimsistemikullanıyorsanızişinizkolay:)
WindowskullanıcılarıiçinözelbirInstallervar.
BubölümdesonolarakdaIRBvekomutsatırıüzerindenRubyçalıştırmayıgöreceğiz.
RubyHakkındaKurulumİnteraktifKullanımRubyKomutuveParametreleri
Bölüm1
8
RubyHakkında1990'lıyıllarınortalarında(1995)Yukuhiro"Matz"MatsumototarafındangeliştirilenRuby,günümüzdeençokkullanılanaçık-kaynakyazılımlarınbaşındageliyor.
Üretkenlik(azkod,çokiş)vebasitliğeodaklı,dinamik,açık-kaynakprogramlamadili.Okumasıveyazmasıkolay,anlaşılabilirnitelikte!
Dilinenbüyükesinkaynaklarıtabiikiyinevarolandiller.Bunlar;Perl,Smalltalk,Eiffel,AdaveLispdilleri.
İlkkararlı(stable)sürümü1995'deyayınlananRuby'ningeliştiricilerintamanlamıyladikkatiniçekmesi2006yılınakadarsürdü.Kezailkversiyonlarıgerçektençokyavaşvesıkıntılıydı.
RubyenbüyükpatlamasınıRubyonRailsframework'üileyaptı.Danimarkalıyazılımcı@dhh'in(DavidHeinemeierHansson)yayınladığıbuframeworkneyazıkkiRubydilininönünebilegeçti.
Kitabıyazdığımanitibariyle(13Temmuz2014,Pazar)Ruby'ninensonsürümü2.1.2(Stabilsürüm)
Güncelleme:Rubyversiyon2.1.3oldu.(26Ekim2014,Pazar)Güncelleme:Rubyversiyon2.1.5oldu.(6Aralık2014,Pazar)Güncelleme:Rubyversiyon2.2.0oldu.(25Aralık2014)Güncelleme:Rubyversiyon2.2.1oldu.(3Mart2015)Güncelleme:Rubyversiyon2.2.2oldu.(1Mayıs2015)Güncelleme:Rubyversiyon2.3.0oldu.(24Aralık2015)
Ruby'ninenönemliözelliğiherşeyinbirnesneyaniObjectolmasıdır.Nesneyibirtürpaket/kutugibidüşünebilirsiniz.Doğalolarak,Objectyaninesneolanbirşeyin,action'ları/method'larıdaolur.
Ruby'ninyaratıcısıMatzşöyledemiş:
Perldilindendahagüçlü,Pythondilindendahaobject-orientedbirscriptdiliolmasınıistedim.
Pekçokprogramlamadilindesayılarprimitive(ilkel/basit)tiplerdir,nesnedeğildirler.HalbukiRuby'desayılardahilherşeynesnedir.Yanisayınınmethod'larıvardır:)
Örnek
RubyHakkında
9
classNumeric
deftopla(x)
self.+(x)
end
end
5.topla(6)#=>11
5.topla(16)#=>21
Sayılara(yaniNumerictipine)topladiyebirmethodekledik...
BlockveMixiniseRuby'ninyineöneçıkanözelliklerindendir.Blockdenenşeyaslındaclosure'dur.Herhangibirmethod'ablocktakılabilir:
search_engines=%w[GoogleYahooMSN].mapdo|engine|
"http://www."+engine.downcase+".com"
end
search_engines#=>["http://www.google.com","http://www.yahoo.com","http://www.msn.
com"]
Buörnekte%wstring'iboşluklarındanayırarakbirarray(dizi)formatınaçeviri.Yanisonuçta%w[GoogleYahooMSN]dediğimizdeelimize["Google","Yahoo","MSN"]dizisigelir.mapmetodubizebudizidenbirEnumaratordönecektirvedo/endkısmıisebizimblockkısmımızdır.Bukonudadahaaçıklayıcıbilgiyi3.bölümdekiBloklarbaşlığıaltındabulacaksınız.
Ruby'debirClass(sınıf)sadecetekbirsınıftantüreyebilir.YaniAclass'ıB'dentüreramaaynıandahemB'denhemC'dentüreyemez.BuPython'damümkünolanbirşeydir.Ruby'deisebununüstesindengelmekiçinclass'larModule'lerikullanır.BirClassNtaneModuleiçerebilir,iştebutürnesnelereMixindenir:
classMyArray
includeEnumerable
end
OrtakkullanılacakmetodlarıyadadeğişkenleriayrıbirModuleolaraktasarlayıp,gerektiğiyerdeincludeederekClass+ModulekarışımındanoluşanMixin'lerortayaçıkar.
DiğerdillerdekigibiExceptionHandling,GarbageCollectorözelliklerininyanısıra,C-Extension'ıyazmakdiğerdilleregöredahakolaydır.İşletimsistemindenbağımsızthreadingimkanısunmaktadır.PekçokişletimsistemindeRubykullanmakmümkündür:Linux/Unix/MacOSX/Windows/DOS/BeOS/OS/2gibi...
Ruby'dentüremişfarklıRubyuygulamalarıdavar:
JRuby,Rubinius,MacRuby,mruby,IronRuby,MagLev,Cardinal
RubyHakkında
10
Sonolarak,TestDrivenDevelopmentyanitest'leyürüyengeliştirmementalitesinineniyioturduğunudüşündüğümdillerdenbiriRuby'dir.Çokgüzeltestkütüphanelerivarvenasılkullanabileceğimizedairtonlarcablog/videositesidemevcut!
Rubyileprogramlamakeğlencelidir!
diyorMatz,haydiohaldebizdebueğlenceyekatılalım:)
RubyHakkında
11
Kurulum
OSXEğerMacOSXkullanıyorsanızilketaptahiçbirşeyeihtiyacınızyok,çünküMacOSX'deRubyhazırkuruluolarakgeliyor.
OSXMavericks(10.9.4)Rubysürümü:ruby2.1.0p0(2013-12-25revision44422)[x86_64-darwin13.0]
LinuxDebianveUbuntukullananokuyucularımız
sudoapt-getinstallruby#yada
sudoaptitudeinstallruby
CentOS,Fedora,yadaRedHatkullananlar:
sudoyuminstallruby
Gentookullananlar;
sudoemergedev-lang/ruby
KaynaktanKurulumRuby'ninsitesindentardosyasınıindirip;
./configure
make
sudomakeinstall
şeklindedekurulumyapabilirsiniz.
Windows
Kurulum
12
BusitedenözelWindowsiçinhazırlanmışRubykurulumpaketiniindiripklasik"next">"next"diyerekkurulumyapabilirsiniz.
RubyVersiyonYöneticileriBazen,kullandığınızhazırkütüphanelerindestekledikleriRubyversiyonlarındakikısıtlamalaryadakişiseltercihinizgibi,farklınedenlerlebirdenfazlaRubysürümüileçalışmakisteyebilirsiniz.Projelerinizdenbiri,örneğinruby1.9.3kullanırken,diğerbirprojenizruby2.1.0kullanıyorolabilir.BuanlardakullandığınızRubyversiyonunukolaycadeğiştirmek,aslındaaktiveetmekdediyebiliriz,için2adetpopülerversiyonyöneticisibulunmaktadır.
Rbenv
Rbenvmeşhur37Signals'ın.AslındaoradaçalışanSamStephensontarafındangeliştirilmişbiraraç.
EğerOSXveHomebrewkullanıyorsanızkurulumçokkolay:
brewinstallrbenvruby-build
Eğerfarklıbirişletimsistemikullanıyorsanız(Linux/Unixtabanlı)
gitclonehttps://github.com/sstephenson/rbenv.git~/.rbenv
#sonraPATH'eekleyin
exportPATH="$HOME/.rbenv/bin:$PATH"
#açılışabunudaekleyin
#hangisinikullanıyorsanız(.bashrc,.profileyada.bash_profile)
eval"$(rbenvinit-)"
KurulumdansonraistediğiniRubyversiyonuiçin;
#kurulabilecekversiyonlarıgöster
rbenvinstall-l
#ruby2.3.0'ıkuralım
rbenvinstall2.3.0
KurulanRuby'yi
SistemgenelinderbenvglobalSadecebulunduğumuzdiziniçinde(UygulamayaÖzel)rbenvlocalAnlık,sadeceShell'derbenvshell
Kurulum
13
aktiveetmeopsiyonlarımızvar.Örneğinprojedizininiçine.ruby-versiondosyasıkoyarveiçinedehangiversiyonukullandığımızıyazarsakodizinegeçtiğimizanRubyversiyonudeğişir.
YaniAprojesindeversiyon2.1.1,Bprojesindeversion1.9.3kullanmakiçin;
cd~/projelerim/A/
echo"1.9.3">.ruby-version
cd~/projelerim/B/
echo"2.1.1">.ruby-version
#bakalımhangiversiyonuaktiveetmişiz?
rbenvversion
RVM
AdındandaanlaşılacağıgibiRubyVersionManageryaniRVMdeaynıRbenvgibiRubyversiyonlarınıkolayyönetmeyisağlıyor.RubydünyasındanRbenv'cilerveRVM'cilerolarakikikanatolduğunusöyleyebilirim.
Kurulumudazordeğil:
gpg--keyserverhkp://keys.gnupg.net--recv-keysD39DC0E3
\curl-sSLhttps://get.rvm.io|bash-sstable
Rbenv'denenbüyükfarklığıGemSetyaniprojebazlıRubypaketiyönetimiözelliği.
BenRbenv'ciolduğumiçinRVMkullanmıyorum.ÖzellikleyenibaşlayanlariçinRVM'iöneriyorum,Rbenv'egöredahakolaykurulumuvekullanımıvar.
Kurulum
14
İnteraktifKullanımRuby'nin(vebenzerdillerin)ençokhoşumagidenözelliğiİnteraktifShellözelliğiolmasıdır.AynıeskidenCommodore64günlerindekigibi,shell'iaçıpRubyyazmayabaşlayabiliriz.
GenelolarakbuinteraktifkullanımREPLolarakgeçer.REPLaslındaReadEvaluatePrintLoop'unbaşharfleridir.Yani,kullanıcıdanbirinput(Read)gelir,bugirdiçalıştırılır(Evaluate),sonuçekranayazdırılır(Print)vesonolarakbaşadönerveyineinputbekler(Loop).
REPLolayı,PythonvePHP'dedevar.
IRBRubykurulumuileberabergelir.YapmanızgerekenTerminal'iaçıpirbyazıpenterabasmak.
irb
irb(main):001:0>print"MerhabaDünya"
MerhabaDünya=>nil
irb(main):002:0>
Örnekleriyaparkençoksıkkullanacağızbukomutu.Keza,dahadageliştirilmişbirversiyonolanprygem'inidegöreceğizilerleyenbölümlerde.
ShellShebangdediğimizyöntemliLinux/UnixtabanlıişletimsistemlerindeRubydosyalarınıaynıbiruygulamaçalıştırırgibikullanabilirsiniz.
test.rbdosyasıolduğunudüşünün;budosya
#!/usr/bin/envruby
puts"Merhabadünya"
şeklindeolsun.Budosyayıçalıştırmakiçinya
rubytest.rb
yada,dosyanınExecuteflag'iniaktifhalegetirerek
İnteraktifKullanım
15
chmod+xtest.rb
./test.rb
çalıştırabilirsiniz.EğerExecuteflag'iniaktifhalegetirmezisenizişletimsistemisizeaşağıdakigibibirhatadönecektir.
permissiondenied:./test.rb
BununsebebidosyanızınExecuteedilebilmesiiçiniznininbulunmamasıdır.Konuyadahayakındanbakmakiçintest.rbdosyasınınbulunduğudizindels-lkomutunuçalıştıralım.
$ls-l
total8
-rw-r--r--1kullanicistaff42May2023:48test.rb
Buradagörüleceğigibi-rw-r--r--dosyanızınsadeceokumaveaktifkullanıcıiçinyazmaiznibulunmakta.EğeryukarıdakigibiExecuteflag'iniaktifhalegetirirsenizdosyanızınsonhaliaşağıdakigibiolacaktır.
$ls-l
total8
-rwxr-xr-x1kullanicistaff42May2023:48test.rb
Şuandadosyanıztümkullanıcılardaokunabilirveçalıştırılabilirdurumda.
İnteraktifKullanım
16
RubyKomutuveParametreleriKurulumişlemleribittiktensonrayadakullandığınızOS(İşletimSistemi)öntanımlıRubyilegeliyorsahemenaşağıdakitestiyapabilirsiniz:
ruby--help
Usage:ruby[switches][--][programfile][arguments]
ruby'yiçağırırken,hershellaracıgibi(binarymidiyim,executablemıdiyimkararveremedim!)Rubydeçeşitliparametreleralabiliyor.BukısımadikkatedelimçünküburadabahsigeçecekSwitch'ler2.BölümdegöreceğimizÖnTanımlıDeğişkenlerileçokalakalı.
Switch Açıklaması
-0[octal]
$/değeridir.(Öntanımlıdeğişkenlerdegöreceğiz)octalyani8'liksistemdedeğeratanır.Örneğinruby-0777şeklindeçalıştırılsa,Ruby,dosyaokumaişlemlerisırasındatekseferdedosyayıokurvetekStringhalinegetirir.
-a -nve-pilebirliktekullanılıncaautosplitmodeolarakçalışır.Yani$F=>$_.splitşeklindeişler.
-c SyntaxCheckyanidosyaiçindekikoduçalıştırmadan,sadecesözdizimikontrolüyaparveçıkar.
-CdirectoryRubyöncebelirtilendirectory'yecd(Shell'debirdizinegeçişyapmak)yaparvedahasonrakoduçalıştırır.ruby-C/tmp/foogibi..
-d,--debugDebugmoddaçalıştırır.Buesnada$DEBUGdeğişkenidetruedeğerinialır.Yanieğerkodunuzuniçindeif$DEBUGgibibirifadekullanabilirvesonucunugörebilirsiniz.
-e'command' KomutsatırındanteksatırdaRubykoduçalıştırmakiçin.ruby-e'puts"hello"'gibi.
-Eex[:in],--encoding=ex[:in] Varsayılankarakterencoding'i(InternalveExternaliçin...)
--external-encoding=encoding -Egibi
--internal-encoding=encoding -Egibi
-Fpattern autosplitiçinvesplit()içinvarsayılanregexpattern'i.$;değeri.
-i in-place-editmod.Lütfenörneğebakın!
-I $LOAD_PATH'eilavepathekleme.
Japonca(KANJI)encodingbelirtilir.UTF-8için-Ku
RubyKomutuveParametreleri
17
kullanılabilir.
-lOtomatiksatırsonu(LineEnding)işlemi.-nve-pileçalışır.Önce$\değişkenine$/değeriatanır,chop!method’uhersatırauygulanır.
-n Komutsatırındakised-nyadaawkgibiçalışır.Sankikodunetrafındaloopvarmışgibidavranaraksüzgeçtengeçirir.
-p -ngibiçalışır,farkı$_dengelendeğeridöngününsonundaprinteder.
-r requirekomutununyaptığıgibiverilendeğerirequireeder.(requirekomutunuileridegöreceğiz)
-s Komutsatırıargümanlarınıparseetme(işleme)özelliğiniaktiveeder.
-S $PATHçevredeğişkeninibulmayıforseeder.Örneğebakınız!
-T Güvenlikseviyesi,taintedkontrolünüdevreyesokmak.$SAFEdeğişkenine-Tilegeçilendeğeratanır.
-v,--verbose Önceversiyonnumarasınıyazarsonradaverbose(Ayrıntılıçalıştırma)moduaktiveeder.Yani$VERBOSEtrueolur.
-w -vileaynıişiyaparsadeceversiyonnumarasınıyazmaz.
-W Uyarıseviyesinibelirler(WarningLevel).0Sessiz,1Ortaşekerli,2Verbose!
-x Shebang'denöncekiyazıyısileratarvealternatifolarakilgilidizinecdyapar.
--copyright Ruby'eaittelifbilgisiniyazar.ruby-Copyright(C)1993-2013YukihiroMatsumoto
--enable=feature[,...],--disable=feature[,...]
ÖrneğinkodunRubyGem'lerinikullanmasınıistemiyorsanız--disable-gemsşeklinde,yada$RUBYOPTçevredeğişkeninidevredışıbırakmakiçin--disable-rubyoptgibi.--disable-allhereközelliğidevredışıbırakır.--enable-allyadadevreyesokar.
--version Versiyonnumarasınıyazar.
--help Yardımsayfasınıgösterir.
ruby--helpdışındadahadetaylıbilgimanrubyyanimanpages'dabulmakmümkündür,bendepekçokşeyeoradanbaktım.
-iörneği:Önceiçindedüzmetinolanbirdosyaoluşturalım:
echovigo>/tmp/test.txt
cat/tmp/test.txt
#vigo
RubyKomutuveParametreleri
18
sonra;
ruby-p-i.backup-e'$_.upcase!'/tmp/test.txt
cat/tmp/test.txt.backup
#VIGO
Neoldu?Amacımız,/tmp/test.txtdosyasında,satırsatırokuyuphersatırdayazanmetniuppercaseyanibüyükharfeçevirmek.Normaldebuişlemi;
ruby-p-e'$_.upcase!'/tmp/test.txt
şeklindekomutsatırındanyapabiliyoruz.Amain-place-editmodveextensionözelliğiile,çalıştırılmışkodçıktısınıbaşkabirdosyadagörüntüleyebiliriz.Bunoktada-idevreyegiriyor.-i.backupsonucungörüntülendiğidosyaoluyor.
-nörneği:Loop'tankastım,sanki;
whilegets
#kod...
end
çevreler.
-sörneği:example_s.rbadındabirdosyamızolsunveiçinde;
print"xyzargümanıkullanıldı\n"if$xyz
yazsın.Budosyayıçalıştırın;
rubyexample_s.rb
Hiçbirçıktıgörmezsiniz.Eğerşuşekildeçalıştırırsanız;
ruby-sexample_s.rb-xyz
şuçıktıyıalırsınız:
RubyKomutuveParametreleri
19
xyzargümanıkullanıldı
-Sörneği:BazıişletimsistemlerinShebangsorunuolabilir.#!/usr/bin/envrubyBugibidurumlarda;
#!/bin/sh
execruby-S-x$0"$@"
şekinde,bashüzeridenRubyscripti'niçalıştırabiliriz.
wip...
RubyKomutuveParametreleri
20
Bölüm2Bubölümde;
Syntax(SözDizimi)Comments(Yorumsatırı)RezerveEdilmişKelimelerDeğişkenTanımlamaveTürleriDuckTypingÖnTanımlıDeğişkenlerPseudoDeğişkenlerOperatörlerGlobalConstants(GenelSabitler)
konularınıişleyeceğiz.
Bölüm2
21
Syntax(SözDizimi)veRezerveKelimeler
Syntax(SözDizimi)Genelolarakçokkolayveanlaşılırbirsyntax'asahiptir.Sankiİngilizceokur/konuşurgibisözdizimibulunur.Örneğin,
Eğera'nındeğeri5'tenbüyükseekrana"Merhaba"yaz
demekistiyorsak;
puts"Merhaba"ifa>5
şeklindeyazabiliriz.
Diğerdillerdenfarklıolarak,Ruby'defonksiyon(method)çağırırkenparantezkullanmakzorunluğuyoktur.Builketaptakafakarıştırıcıgibidursada,alışıncanekadarkolayokunabilirolduğunugörüyorsunuz.Mecburideğil,yaniparantezkullanmanızdasorunyok.Parantezlikullanım;
defgreet_user(user_name)
puts"Merhaba#{user_name}"
end
greet_user("Uğur")#MerhabaUğur
Eğerparantezkullanmazsak;
defgreet_useruser_name
puts"Merhaba#{user_name}"
end
greet_user"Uğur"#MerhabaUğur
şeklindeolur.Keza,pekçokdilde,fonksiyoneğerbirşeydönersegeriye,mutlakareturnkomutukullanılır.Ruby'debunadagerekyok.Çünkühermethod(yaniFonksiyon)mutlakadefaultolarakbirşeydöner.Hiçbirşeydönmesebilenildöner.Bubakımdanda;
defgreet_useruser_name
"Merhaba#{user_name}"
end
putsgreet_user"Uğur"#MerhabaUğur
Syntax(SözDizimi)veRezerveKelimeler
22
şeklindekullanabiliriz.Korkmayın,kafalarkarışmasın.Detaylaraileridegireceğiz.
Comments(YorumSatırları)HerdildeolduğugibiCommentoutyani"işaretlikısmıçalıştırma"demekiçinkullandığımızşeyRuby'dedevar.
Commentiçin#işaretikullanılıyor.Geneldeline-commentyanisatırbazlı,veblock-commentyanikodbloğubazlıyorumyapmaşekillerivar.
#Busatırline-comment,yaniteksatırlıyorum
#Bukısımblock-comment
#
#deftest_user
#true
#end
#yada
=begin
Buyorum...
Budayorum...
Hattabuda...
=end
Gördüğünüzgibiblock-commentiçinilaveolarak=beginve=endkelimelerikullanılabiliyor.
RezerveEdilmişKelimelerHerdildeolduğugibiRuby'dededahaöncedenrezerveedilmişbazıkelimelerbulunmaktadır.Bukelimelerideğişkenyadamethodadıolarakkullanamıyoruz.BukelimelerRubykomutlarıveözeldurumlariçinrezerveedilmiş.
Syntax(SözDizimi)veRezerveKelimeler
23
Kelime Kelime
BEGIN next
END nil
alias not
and or
begin redo
break rescue
case retry
class return
def self
defined? super
do then
else true
elsif undef
end unless
ensure until
false when
for while
if yield
in __FILE__
module __LINE__
Syntax(SözDizimi)veRezerveKelimeler
24
DeğişkenlerDeğişkendenenşey,yaniVariable,nesneyeatanmışbirişaretçidiraslında.Nedemiştik?Ruby'deherşeybirnesneyaniObject.Bunesnelereerişmekiçinaracıdırdeğişkenler.
Farklıfarklıtürlerivardır.Birazdanbunlaradeğineceğiz.Enbasitanlamdadeğişkentanımlamak;
a=5
user_email="[email protected]"
şeklindeolur.Yukarıdakiörnekteaveuser_emaildeğişkeninadıdır.Değeriiseeşittirişaretindensonragelendir.
Yaniyukarıda;ayasayı[email protected]ğerleriatanmıştır.
Değişkenler
25
RubyDuckTypingşeklindeçalışır.Yaniatamayapmadanöncenetürbirdeğeratamasıyapacağımızıbelirtmemizegerekyok.Rubyzatena=5dediğimizde,"Hmmm,budeğerFixnumtüründe"diyedeğerlendirir.
DuckTypingdemekşudur;Eğerördekgibiyürüyorsa,ördekgibisesçıkartıyorsaeozamanbubirÖrdektir!İngilizcesi;
WhenIseeabirdthatwalkslikeaduckandswimslikeaduckandquackslikeaduck,Icallthatbirdaduck
Yani,birkuş,eğerördekgibiyürüyorsa,ördekgibiyüzüyorsaveördekgibisesçıkarıyorsabenbunaÖrdekderim!
MetinselAtamalarveTırnakKullanımıYerigelmişkenhızlıcabirkonuyadeğinmekistiyorum.Metinseldeğişkenlertanımlarken(String)eşitlikesnasındatekyadaçifttırnakişaretikullanabiliriz.Fakataradakifarkıbilerekkullanmamızgerekir.
Stringiçindedeğişkenkullanımıyaptığımızzamanyani;
a=41
puts"Siztam#{a}yaşındasınız"
gibibirdurumda,gördüğünüzgibi#{a}şeklindeyazıiçindedeğişkenkullandık.Bukodunçıktısıaşağıdakigibiolacak.
Siztam41yaşındasınız
FormatolarakRuby'de,#{BUKISIMDAKODÇALIŞIR}şeklindeistediğimizkoduçalıştırmayetkimizvar.Buişlemsadeceçifttırnakkullanımındageçerlidir.Başkabirörnekvermekgerekirse;
a=41
puts"Siztam#{a+2}yaşındasınız"
YukarıdakiörnekteRubya+2komutunuçalıştıracaktırvesonuçolarak43değerinibulacaktırvebunuekranayazdıracak.Yanisonuç:
Siztam43yaşındasınız
şeklindeolacaktır.Ancakaynıkodutektırnakkullanarakyapmışolsaydık;
Değişkenler
26
a=41
puts'Siztam#{a}yaşındasınız'
çıktısı:
Siztam#{a}yaşındasınız
olacaktı.Tektırnakiçindebuişlemçalışmaz!
Local(Bölgesel)BölgeselyadaYereldeğişkenler,birscopeiçindekideğişkenlerdir.Scopenedir?Kodunçalıştığıbölgeolaraktanımlayabiliriz.Butürdeğişkenlermutlakaküçükharfleyada_(underscore)işaretiilebaşlamalıdır.Kesinlike@,@@yada$işaretigibiönekleralamazlar.
out_text="vigo"
defgreet_user(user_name)
out_text="Merhaba#{user_name}"
end
putsgreet_user("vigo")#Merhabavigo
putsout_text#vigo
Programçalıştığındaout_textdeğişkeninindeğerivigoolarakatanmaktadır.Dahasonra6.satırdagreet_usermethod'u(fonksiyonu)çalıştığında,omethoduniçerisindeout_textdeğişkeninindeğerideğiştiriliyorgibigörünüyor.Dahasonra7.satırdaout_textdeğişkeninindeğeriputsmethoduileekranayazdırılmaktadır.Ancakburadaçıktılarabaktığınızdamethoduniçerisindekiout_textdeğişkenindekideğişim,programınenbaşındatanımladığımızout_textdeğişkenindeğerinietkilememiştir.Methodiçerisindekalmıştır.Buradamethodiçerisindekiout_textdeğişkeniaslındalocalvariableyaniyereldeğişkenşeklindeçalışmaktadır.
Global(Genel)$işaretiylebaşlayantümdeğişkenlerGlobaldeğişkenlerdir.Kodunherhangibiryerindekullanılabilirveerişilebilir.
Değişkenler
27
$today="Pazartesi"
defgreet_user(user_name)
out_text="Merhaba#{user_name},bugün#{$today}"
putsout_text
end
puts"Bugüngünlerdenne?#{$today}"
greet_user("vigo")#Merhabavigo,bugünPazartesi
BuörnektekiGlobaldeğişken$todaydeğişkenidir.
Constants(Sabitler)Sabitnedir?Değiştirelemeyendir.Yanibutürdeğişkenler,kibudeğişkendeğildir:),sabitolarakadlandırılır.KuralolarakmutlakaBÜYÜKHARF'lebaşlar!Bazendetamamenbüyükharflerdenoluşur.
My_Age=18
your_age=22
putsdefined?(My_Age)#constant
putsdefined?(your_age)#local-variable
My_Agesabit,your_agedeyereldeğişken...
Ruby'deilginçbirdurumdahavar.Constant'larmutableyanideğiştirilebilir.Nasılyani?
My_Age=18
putsdefined?(My_Age)#constant
puts"My_Age:#{My_Age}"#My_Age:18
My_Age=22
putsdefined?(My_Age)#constant
puts"My_Age:#{My_Age}"#My_Age:22
amawarningyaniuyarımesajıaldık!
untitled:6:warning:alreadyinitializedconstantMy_Age
untitled:1:warning:previousdefinitionofMy_Agewashere
My_Agesabiti6.satırdazatentanımlıydı.Öncekideğeride1.satırdadiyebizeikazettiRubyyorumlayıcısı.
Değişkenler
28
ParalelAtamaHemennedemekistediğimibirörnekleaçayım:
x,y,z=5,11,88
putsx#5
putsy#11
putsz#88
a,b,c="Uğur",5.81,1972
putsa#Uğur
putsb#5.81
putsc#1972
x,y,z=5,11,88derkentekharekettex=5,y=11vez=88yaptık.İştebuparalelatama.
InstanceVariableInstancedediğimizşeyClass'dantüremişolannesnedir.Bukonuyudetaylıolarakilerideinceleyeceğiz.Sadeceönbilgiolmasıadınadeğiniyorum.@işaretiilebaşlarlar.
classUser
attr_accessor:name
definitialize(name)
@name=name
end
defgreet
"Merhaba#{@name}"
end
end
u=User.new("Uğur")
putsu.greet#MerhabaUğur
putsu.name#Uğur
u.namediyeçağırdığımızşeyUserclass'ındantüremişolanunesnesininInstanceVariable'ıyanitüremişnesneyeaitdeğişkenidir.Fazlatakılmayın,Classkonusundabolboldeğineceğiz...
ClassVariableClass'aaitdeğişkendir.Dikkatedinburadatüreyenbirşeyyok.@@ilebaşlar.Kullanmadanöncebudeğişkenimutlakainitetmelisiniz(Yaniöntanımlamayapmalısınız)
Değişkenler
29
classUser
attr_accessor:name
@@instance_count=0#Kullanmadanönceinitettim
definitialize(name)
@name=name
@@instance_count+=1#Class'danherinstanceoluşmasındasayacı1arttırıyorum
end
defgreet
"Merhaba#{@name}"
end
defself.instance_count#burasıöneli
@@instance_count
end
end
user1=User.new("Uğur")
user2=User.new("Ezel")
user3=User.new("Yeşim")
puts"KaçdefaUserinstance'ıoldu?#{User.instance_count}"#KaçdefaUserinstance'
ıoldu?3
Eğerkafanızkarıştıysasorundeğil,Classkonusundahepsininüzerindentekrargeçeceğiz.
Değişkenler
30
ÖnTanımlıDeğişkenlerRuby,birkısımöntanımlıyaniPredefineddeğişkenlerlegeliyor.Değişkenlerinneolduğunu;
putsglobal_variables
şeklindegörebiliriz.Öndenbubilgilerivermekzorundayım,dahagenişkullanımıvetamolarakneişeyaradıklarınıilerikibölümlerdedahaiyianlayacaksınız.
Değişken Açıklama
$! raiseileatananexceptionbilgisidir.rescueileerişilir.
$@ Sonexception'aaitbacktrace(birtürlog)bilgilerinintutulduğudizi(Array)
$& Sonyakalananmatch'intutulduğuString(Regexkonusundagöreceğiz)
$` Sonyakalananmatch'insolundakalankısım
$' Sonyakalananmatch'insağındakalankısım
$+ Enyüksekgroupmatch'intutulduğuyer.(Regexyaparkengroupyakalamakonusundagöreceğiz)
$1,$2,...,$9 Yine,Regexilepaternyakalama(patternmatching)yaptığımızda,yakaladığımızşeylerinsıranumarası.
$~ Oankikapsamaalanında(scope)sonyakalananlailgilibilgilerintutulduğudeğişken
$=
Regexileuğraşırken,karakterlerinbüyük/küçükharfeduyarlılığıileilgiayarlarvardır.Örneğinbüyük/küçükharffarkıolmadanaramakyaparken(caseinsensitive)budeğişkeneatamayaparız.Varsayılandeğer(default)nil'dir
$/
Dosyadanokumayapılırkensatırlarınnasılayrıldığınıntespitedildiğideğişkendir.Eğernilolarakatarnırsa,dosyaokumasıesnasındasatır-satırokumayerinetümdosyabirandaokunur.
$\Budaçıktıiçinayraçtır.printveputsgibikomutlardaIO#writegibiişlemlerdekullanılır.Varsayılandeğernil'dir
$, printveArray#joindekullanılanayraçtır.
$; String#splitdekullanılanayraçtır.
$. Dosyaişlemlerindesonokunandosyanınaktifsatırnumarasınıverir.
$< Aynıshelldekiekleme(concatenation)işlemigibisanaleklemeyapar.
ÖnTanımlıvePseudo(GerçekOlmayan)Değişkenler
31
$> printveprintfişlemiiçinvarsayılançıktıdır.Varsayılandeğeride$stdout
$_ getsveyareadlineilealınansonsatırdır,cinsiString'dir.
$0 Çalıştırılanscript'indosyaadıdır.
$* Komutsatırıişlemlerinde,dosyayageçilenargümanlarınsaklandığıdeğişkendir.
$$ Çalıştırılanscript'inişlemnumarası(ProcessNumber)
$? Çalıştırılansonaltişlemin(ChildProcess)durumu.
$: ModüllerveekdosyalariçinPath(LoadPath_)bilgisi.requirekomutundagöreceğiz.
$" requireileyüklenendosyalarınadlarınıntutulduğudizi(Array)
$DEBUGAdındandaanlaşıldığıgibi,eğerDEBUGmoddaçalıştırmayapıyorsak(kibunu-dileyaparız)oluşanherexception'ın$stderrdeğişkenineatanmasınısağlar.
$KCODEKodyazdığımızscriptdosyasınınencodingtipiniseçmemizeyarar.Sonsürümlerdeihtiyaçkalmadı,herşeydefaultolarakUTF-8çalışıyor.
$FILENAMEKomutsatırındanargümanolarakdosyageçtiğimizdegeçilendosyanınadınıalmakiçinkullanılır.AslındaARGF.filenameileaynıişiyapar.
$LOAD_PATH $:ileaynıişiyapanalias'dır(alias=takmaad)
$SAFE
Güvenlikseviyesidir.Varsayılandeğer0dır.Budereceler0'dan4'ekadardır.Kodgüvenliğivekilitlemeyapmakiçinkullanılır.Birazkarmaşıkbirkonudur:)Örneğin,eminolmadığınızbirkütüphanekullanırkenkodunuzugüvenlihalegetirmekiçin,kodbloğununönüne$SAFE=4ekerseniz,takipedenkodarrayhashvestringlerdehiçbirmodifikasyonyapamaz!Hattapekçokşeyiyapamaz!
$stdin Standartgiriş.
$stdout Standartçıkış.
$stderr Giriş/Çıkışhatabildirimi.
$VERBOSE Kerneltarafındanüretilentümuyarımesajlarının(warninggibi...)görüntülenmesiiçinkullanılır.
$-0 $/ileaynıişiyapar.
$-a Komutsatırındançalıştırmayaparkan-aatamasıyapılmışsa$-atruedöner.
$-d $DEBUGileaynıişiyapar.
$-F $;ileaynıişiyapar.
$-i Budeğişkenin-place-editmoddaextension'ısaklar.
$-I $:ileaynıişiyapar.(Büyüki)
ÖnTanımlıvePseudo(GerçekOlmayan)Değişkenler
32
$-l Eğer-lissetedilmişsetruedöner.ReadOnlyyanisadeceokunur,değerideğiştirilemez!(Küçükl)
$-p Eğer-pissetedilmişsetruedöner.ReadOnlyyanisadeceokunur,değerideğiştirilemez!
$-K $KCODEileaynıişiyapar.
$-v $VERBOSEileaynıişiyapar.
$-w Eğer-wsetedilmişsetruedöner.
$-W WarningLevelyanioluşabilecekhatalarvsileilgili0,1yada2.seviyedeuyarımesajlarıgöstermekiçin.
$LOADED_FEATURES $"ileaynıişiyapar.
$PROGRAM_NAME $0ileaynıişiyapar.
Pseudo(GerçekOlmayan)DeğişkenlerDeğişken(Variable)gibigörünenamaSabit(Constant)gibidavrananvekesinlikledeğeratamasıyapılamayanşeylerdir.
Değişken Açıklama
self Alıcınesneninoankiaktifmethod’u.YanibubirClassisekendisi...
nil Tanımıolmayan(Undefined)şeylerindeğeri.
true Mantıksal(Boolean)işlem,anlayacağınızgibitrueyani1
false true'nuntersi(Boolean)yani0
__FILE__ Çalışankaynakkoddosyasınınadı
__LINE__ Çalışankaynakkoddosyasındaki,oankiaktifsatırınnumarası
ÖnTanımlıvePseudo(GerçekOlmayan)Değişkenler
33
OperatörlerOperatörlerçeşitlikontrolleriyapmakiçinkullanılır.Hattabazılarıaynızamandamethodolarakçalışır.Bazıoperatörlerinbirdenfarklıişlemivardır.Örneğin+hemmatematikişlemiolantoplamaiçinhemdepozitifdeğerkontrolüiçinkullanılabilir.
Operatör Açıklama Methodmu?
:: İkitaneikinokta.Scoperesolutionanlamındadır.ClassveModülkonusundadetaylarıgöreceğiz.
[] Referans,set Evet
[]= Referans,set Evet
** Üssü,kuvveti Evet
+ Pozitif Evet
- Negatif Evet
! Mantıksaluzlaşma
~ Tamamlayıcı Evet
* Çarpma Evet
/ Bölme Evet
% Modülo(Kalan) Evet
+ Ekleme Evet
- Çıkartma Evet
<< Solakaydır Evet
>> Sağakaydır Evet
& Bitseviyesindeand(Ve)işlemi Evet
| Bitseviyesindeor(Veya)işlemi Evet
^ Bitseviyesindeexclusiveor(Veya'nıntersigibi)işlemi Evet
> Büyüktür Evet
>= Büyükveeşit Evet
< Küçüktür Evet
<= Küçükveeşit Evet
<=> Eşitlikkarşılaştırmaoperatörü(Spaceshipyaniuzaygemisi) Evet
== Eşitlik Evet
=== Denklik Evet
Operatörler
34
!= Eşitdeğil
!~ Yakalanmayan(notmatch)
=~ Yakalanan(match) Evet
&& Mantıksalve(and)
|| Mantıksalveya(or)
.. Range'ikapsayan Evet
... Range'ikapsamayan
?: Ternary
= Atama
+= Arttırmaveatama
-= Eksiltmevetama
*= Çarpmaveatama
/= Bölmeveatama
%= Modüloveatama
**= Üssüveatama
<<= Bitseviyesindesolakaydırmaveatama
>>= Bitseviyesindesağakaydırmaveatama
&= Bitseviyesindeandveatma
|= Bitseviyesindeorveatama
^= Bitseviyesindeeorveatama
&&= Mantıksalandveatama
||= Varlıkataması(ExistentialOperator)
İlkbakıştainsanınaklınıdurduranbirsürügaripişaretlerbunlardeğilmi?Hemenörneklerlepekiştirelim.
a=[]
a.class#=>Array
a.length#=>0
[]=KullanımÖrneği
a=[]#Bubirdizi/Array
a.[]=5,"Merhaba"#0indekli,5.elemanMerhabaolsun
pa#[nil,nil,nil,nil,nil,"Merhaba"]
Operatörler
35
UnaryOperatörleriUnarydemek,+=,-=,*=gibiişlemleriyaptığımızoperatörler.Yanix+=5dediğimizde(x'indeğerine5eklevesonucutekrarx'eata)aslındaUnaryoperatörükullanmışoluruz.
Keza,aşağıdakiörnektekigibikullanımlardaekfaydasağlamışoluruz:
str="MerhabaDünya"
classString
def-@
reverse
end
end
pstr#"MerhabaDünya"
p-str#"aynüDabahreM"
Operatörler
36
GlobalConstants(GenelSabitler)Ruby,öntanımlıolarakçeşitlisabitlerlebirliktegeliyor.BenanitibariyleMacOSXüzerinde,rbenvileruby2.1.0kullanıyorum.BubağlamdasizinkullandığınızRubyversiyonunagöredeğişkenliklerolabilir.
Sabit Değeri
TRUE Anlaşılacağıgibibutruedeğeri
FALSE Budafalsedeğeri
NIL nil
STDIN Standartgiriş.$stdiniçinvarsayılandeğer.
STDOUT Standartçıkış.$stdoutiçinvarsayılandeğer.
STDERR Standarthata.$stderriçinvarsayılandeğer.
ENV Aktifçevredeğişkenlerinin(EnvironmentVariables)bulunduğuHash
ARGF $<ileaynıişiyapıyor.
ARGV $*ileaynıişiyapıyor.
DATA HerhangibirRubyscriptdosyasında,__END__sonrasınayazılanşeylerinsaklandığıdeğişken.
RUBY_VERSION "2.1.0"
RUBY_RELEASE_DATE "2013-12-25"
RUBY_PLATFORM "x86_64-darwin13.0"
RUBY_COPYRIGHT "ruby-Copyright(C)1993-2013YukihiroMatsumoto"
RUBY_DESCRIPTION "ruby2.1.0p0(2013-12-25revision44422)[x86_64-darwin13.0]"
RUBY_ENGINE "ruby"
RUBY_PATCHLEVEL "0"
RUBY_REVISION 44422
GlobalConstants(GenelSabitler)
37
Bölüm3Bubölümde;
Methods(Fonksiyonlar)Blocks(Bloklar)ProcveLambdaConditionalStatements(Koşullar)
Konularınıişleyeceğiz.
Bölüm3
38
Methods(Fonksiyonlar)Programlamaparçacıklarınınve/veyaifadelerinbirarayatoplandığışeydirmethod.Aslındalisematematiğindenhepimizaşinayız.
Bildiğinizmatematikfonksiyonu.Bundanböylefonksiyonyerinemethodkullanacağım.ÇünküRubydemekneredeyseObje(Nesne)veMethod(Method)demek.
Öncekikonulardagördüğümüzoperatörlerinneredeysehepsibirmethod!HemenMethodDefinition'ayaninasılmethodtanımlandığınabirgözatalım.
defmerhaba
"Merhaba"
end
merhaba#=>"Merhaba"
defveendanahtarkelimeleriarasınamethod’unadıgeldi.Öncemethod’utanımladık,sonraçağırdık.
Ruby'deherşeymutlakageriyebirşeydöner.Nedemekbu?Prensipolarakmethod’larzincirolarakçalıştığıiçin,methoddenenşeydeaslındabirfonksiyonvefonksiyondenenşeydebirdiziişleminyapılıpgeriyesonucundönüldüğübirtaşıyıcıaslında.
Birörnekvermekiçinhemenirbyegeçelim:
irb(main):001:0>puts"Merhaba"
Merhaba
=>nil
irb(main):002:0>
puts"Merhaba"önceişiniyaptıveçıktıolarakMerhabaverdi.sonra=>nildikkatiniziçektimi?
Çünküputsmethod’uişiniyaptıbitirdivegeriyenildöndü!Pekidahaöncekiprogramlamatecrübelerimizedayanak,geriyedöndüişinihangikomutyapmışolabilir?
Pekçokdildefonksiyondanbirşeygeridönmekiçinreturnkelimesikullanılır.Ruby'dedekullanılıramazorunludeğildir.YukarıdakidefmerhabaörneğindereturnkullanmamamızarağmengeriyeMerhabadönebildi.
Ruby'demethodlariçerisindekiçalıştırılanensonsatırındeğerinidöndürür.Ancaksizdahaöncesindeözelliklereturnanahtarkelimesiilebirsonuçdönmezseniz.Birörneklekonuyupekiştirelim.
Methods(Fonksiyonlar)
39
defmerhabaBir
m="Merhaba"
n="Ornek"
end
defmerhabaIki
m="Merhaba"
n="Ornek"
return"ReturnOrnek"
end
putsmerhabaBir#Sonuç:Ornek
putsmerhabaIki#Sonuç:ReturnOrnek
İştebuRuby'ninözelliği.Koduokurkenbunubilmezsekkafamızsüperkarışabilir.
defiletanımlananmethod’u,undefileyokedebilirsiniz.
defmerhaba
"Merhaba"
end
merhaba#=>"Merhaba"
undefmerhaba
merhaba#=>
#~>-:9:in`<main>':undefinedlocalvariableormethod`merhaba'formain:Object(Na
meError)
Gördüğünüzgibiundefinedlocalvariableormethod..Object(NameError)hatasınıaldık.
Method’larargümanalabilir.Yanifonksiyona,doğalolarak,parametregeçebilirsiniz.
defmerhaba(isim)
"Merhaba#{isim}"
end
merhaba("vigo")#=>"Merhabavigo"
aynıörneğiaşağıdakigibideyazabiliriz:
defmerhabaisim
"Merhaba#{isim}"
end
merhaba"vigo"#=>"Merhabavigo"
Methods(Fonksiyonlar)
40
Method’utanımlarkenveçağırırkenparantezkullanmadık!Bualışmanızgerekenönemlikonulardanbirisi.Şahsenben,dahaöncehiçbirprogramlamadilindeböylebirşeygörmedim!
Bazıdurumlara,argümanalanmethodçağırırken,argümanıntipinegöre,eğerparantezkullanmadançağırmayaparsanızwarningalabilirsiniz!
MethodYazmaKuralları(MethodConventions)Ruby,pekçokkonudarahatgibigörünsebilebazıkurallarıvartabi.Özelliklemethod’larınsonkarakteriileilgili.Eğerbirmethod’unsonkarakteri?isebuomethod’untrueyadafalseyaniBooleanbirdeğerdöneceğiniifadeeder.
a="ali"
b="ali"
a.eql?b#=>true
a.eql?(b)#=>true
.eql?method’ueşitliğikontroledervemutlakasonuçBooleandöner.
Eğermethod’unsonkarakteri!(Ünlem)ise;bu,omethod’untehlikelibirişyaptığınıanlatır.Yaniilgilinesneninkopyalanmadandireküzerindedeğişiklikyapacağıanlamınagelir.
a="deneme"
a.upcase#=>"DENEME"
a#=>"deneme"
a.upcase!#=>"DENEME"
a#=>"DENEME"
adeğerideneme..upcaseileorijinaldeğerideğiştirmedenuppercase(Büyükharf)yaptık.Değerikontrolettiğimizdehalenküçükharfolduğunugördük..upcase!kullandığımızandadeğişkeninorijinaldeğerinidebozduk.
Eğerbirmethod=ilebitiyorsa,bu,omethod’unbirsettermethod’uolduğuanlamınagelirveClassileilgilibirkonudur.
Methods(Fonksiyonlar)
41
classUser
defemail=(email)
@email=email
end
end
u=User.new
u#=>#<User:0x007ff7229ed880>
u.email="[email protected]"
u#=>#<User:0x007ff7229ed880@email="[email protected]">
VarsayılanArgümanlar(DefaultArguments)Methodargümanlarınavarsayılandeğerleratayabilirsiniz.Bu,eğermethodagönderilmesibeklenenargümangelmemişseotomatikolarakdeğeratamayapmayısağlar.
defmerhaba(isim="insalık!")
"Merhaba#{isim}"
end
merhaba#=>"Merhabainsalık!"
merhaba("vigo")#=>"Merhabavigo"
Parametregeçmedençağırdığımızda,tanımladığımızvarsayılan(default)değeratandı.
DeğişkenSayıdaArgümanlar(Variable-LengthArguments)Bazıdurumlardamethod’adeğişkensayıdaolarakparametregeçmekgerekebilir.Budurumdaargümanınbaşına*işaretigelir.Busayedeoargümanartıkbirdizi(Array)halinegelir.
defmerhaba(*isimler)
"Merhaba#{isimler.join("ve")}"
end
merhaba("vigo")#=>"Merhabavigo"
merhaba("vigo","yeşim","ezel")#=>"Merhabavigoveyeşimveezel"
merhaba"dünya","uzay","evren","ay"#=>"Merhabadünyaveuzayveevrenveay"
Keza,şuşekildedekullanılabilir:
Methods(Fonksiyonlar)
42
defcustom_numbers(first,second,*others)
puts"ilksayı:#{first}"
puts"ikincisayı:#{second}"
puts"diğersayılar:#{others.join(",")}"
end
custom_numbers1,2,50,100#=>nil
#>>ilksayı:1
#>>ikincisayı:2
#>>diğersayılar:50,100
Method’aTakmaİsimVermek(Aliasing)Varolanbirmethod’u,başkabirisimleçağırmak.BuaslındaClasskonusuylaçokilintiliamakısacadeğinmekistiyorum.
defmerhaba(isim)
"Merhaba!#{isim}"
end
aliasnabermerhaba
merhaba"Uğur"#=>"Merhaba!Uğur"
naber"Uğur"#=>"Merhaba!Uğur"
Formülşu:aliasTAKMAADORİJİNALyanialiasnabermerhabaderken,merhabamethod’unatakmaadolaraknaberitanımladık!
Unutma!
returnkullanmadanmethod’dangeridönüşyapılabilirParantezkullanmadanmethodtanımlanabilirParantezkullanmadanmethodçağırılıpparametregeçilebilir.?ilebitenmethodmutlakatrueyadafalsedöner.!ilebitenorijinaldeğerimutlakadeğiştirir.=ilebitensetter'dır.
Methods(Fonksiyonlar)
43
Blocks(Bloklar)Blokolayı,benceRuby'ninençılgınözelliklerindenbiri.Aslındabukonu,neredeysebaşlıbaşınabirkitapkonusuolabilir.GeneldeBlock,Proc,Lambdaüçlemesiolarakanlatılır.
Kitabımız101yanigirişseviyesindeolduğuiçin,kafalarıminimumkarıştırmaadınabasitşekildedeğineceğim.
Blok'lar,geneldeClosureyadaAnonimfonksiyonlarolaraktanımlanır.Sankimethodiçindebaşkabirmethod’uişaretedenyadadeğişkenlerimethod’lararasındapaylaşankapalıbirortamgibidirler.
Geneldeya{}ileyadado/endilesarmalanmışlardır.
family_members=["Yeşim","Ezel","Uğur","Ömer"]
family_members.eachdo|member_name|
putsmember_name
end
#Yeşim
#Ezel
#Uğur
#Ömer
Aynıkod:
family_members=["Yeşim","Ezel","Uğur","Ömer"]
family_members.each{|member_name|putsmember_name}
#Yeşim
#Ezel
#Uğur
#Ömer
şeklindedeyazılabilirdi.do/endyada{}arasındakalankısımBlockkısmıdır.
family_membersbirArrayyanidizidir.Eğerputsfamily_members.classdersekbizeArrayoldunusöyler.Array'ineachmethod’ubizeblockişlemeşansınısağlar.
KomutsatırındariArray#eachdersekbizeArray'ineachmethod’uylailgilitümbilgilergelir.
dokomutundanhemensonragelen|member_name|bizimkafamızagöretanımladığımızbirdeğişkendirveArray'inherelemanıbudeğişkeneatanır.
Blocks(Bloklar)
44
Enumerationbölümündebunlardansıkçabahsedeceğiz.Blocklarınesasgücüyieldolayındangelir.Hemenbirörnekverelim:
deftest_function
yield
end
test_function{
puts"Merhaba"
}
#Merhaba
test_functiondo
puts"Benblockiçindengeliyorum"
end
#Benblockiçindengeliyorum
test_functiondo
[1,2,3,4].eachdo|n|
puts"Sayı#{n}"
end
end
#Sayı1
#Sayı2
#Sayı3
#Sayı4
test_functionadındabirfonksiyonumvar(yanimethod’umvar)Hiçparametrealmıyor!amaBlockalıyor.İlkindecurlybraceile(yani{ve}),ikincisindedo/endile,sonörnektedo/endileveiçkısımdabaşkabiriterasyonlakullandım.
Kabaca,fonksiyonakodbloğugeçtim.
Peki,yaşuşekildekullansaydımtest_function?yanihiçbirşeygeçmeden?Alacağımhatamesajı:
noblockgiven(yield)
olacaktı.Demekkiblockgeçilipgeçilmediğinianlamanınbiryoluvar:)
deftest_function
ifblock_given?
yield
else
puts"Lütfenbanablockveriniz!"
end
end
Blocks(Bloklar)
45
block_given?ilebukontrolüyapabiliyoruz.Şimdibirazdahakafakarıştıralım:)
defnumerator
yield10
yield4
yield8
end
numeratordo|number|
puts"Geçilensayı#{number}"
end
Örnekte,yieldblockiçindengelenkodbloğunubirfonksiyongibiçağırıyor,çağırırkendebloğaparametregeçiyor.Dikkatettiysenizkaçtaneyieldvarsaokadarkezblockçağırıldı(calledildi_)
defprint_users
["Uğur","Yeşim","Ezel"].eachdo|name|
yieldname
end
end
print_usersdo|name|
puts"KullanıcıAdı:#{name}"
end
#KullanıcıAdı:Uğur
#KullanıcıAdı:Yeşim
#KullanıcıAdı:Ezel
Fonksiyoniçinefonksiyongeçtikgibi.
Enumeration/Numberbölümündedegöreceğizamahemenhızlıbir-ikiörnekvermekistiyorumblokkullanımıylailişkili.
5.times{puts"Merhaba"}
5.times{|i|puts"Sayı#{i}"}
5.timesdo|i|
puts"Sayı#{i}"
end
Not:Aslındatimessayılaraaitbirmethodveyukarıdakiörneklerdegördüğünüzgibiblokgeçebiliyoruzkendisine.
Blocks(Bloklar)
46
ProcveLambdaBlockkullanımınıdahadinamikveprogramatikhalegetirmekiçinProceduresyadageneladıylaProcs,object-orientedRuby'ninvazgeçilmezlerindendir.
Bazen,herseferindeaynıbloğusürekligeçmekgerektiğindeimdadımızaProcyetişiyor.Nasılmı?
Düşününkibirmethod'unuz(fonksiyonunuz)olsun,vebumethod’udinamikolarakprogramlayabilseniz?
defmultiplier(with)
returnProc.new{|number|number*with}
end
Çarpmayaptırandinamikbirfonksiyon.Sayıyıkaçileçarpacaksakwitheosayıyıgeçiyoruz.
multiply_with_5=multiplier(5)
Elimizdegeçtiğimizsayıyı5ileçarpacak,fonksiyondantüremişbirfonksiyonoluştu.Eğermultiply_with_5acabaneymişdersek?
putsmultiply_with_5
##<Proc:0x007fcc9c94a938@/Users/vigo/Desktop/ruby101_book_tests.rb:2>
putsmultiply_with_5.class
#Proc
GördüğünüzgibielimizdebiradetProcobjesivar!.Haydikullanalım!
putsmultiply_with_5.call(5)#25
putsmultiply_with_5.call(10)#50
Bukadarkasmadan,basitbirmethodileyapsaydık:
defmultiplier(number,with)
returnnumber*with
end
putsmultiplier5,5#25
şeklindeolurdu.Benzerbirörnekdahayapalım:
ProcveLambda
47
multiplier=Proc.new{|*number|
number.collect{|n|n**2}
}
multiplier.call(1)#=>[1]
multiplier.call(2,4,6)#=>[4,16,36]
multiplier[2,4,6].class#=>Array
AzilerideArraykonusundagöreceğimizcollectmethod'unukullandık.BumethodileArray'inherelemanınıokuyorvekaresinin**2alıyoruz.*işaretiyineArray'degöreceğimizsplatözelliği.YanigeçilenparametregrubunuArrayolarakdeğerlendirdiyoruz.
LambdaPython'lauğraşanokurlarımızLambda'yaaşinaolabilirler.Procileilkgözeçarpanfark,argümanolarakgeçilenparametrelerinsayısıönemlidirLambda'da.AynıProcgibiçalışır.
custom_print=lambda{|txt|putstxt}
custom_print.call("Hello")#Hello
Eğer2parametregeçseydik:
custom_print=lambda{|txt|putstxt}
custom_print.call("Hello","World")
#ArgumentError:wrongnumberofarguments(2for1)
Yada;
l=lambda{"Merhaba"}
putsl.call#Merhaba
Başkabirkullanım;
l=lambdado|user_name|
ifuser_name=="vigo"
"Selamvigo!nasılsın?"
else
"Selamsana#{user_name}"
end
end
putsl.call("vigo")#Selamvigo!nasılsın?
putsl.call("uğur")#Selamsanauğur
ProcveLambda
48
ProcveLambdaFarkı
defarguments(input)
one,two=1,2
input.call(one,two)
end
putsarguments(Proc.new{|a,b,c|puts"#{a}ve#{b}ve#{c.class}"})
#1ve2veNilClass
putsarguments(lambda{|a,b,c|puts"#{a}ve#{b}ve#{c.class}"})
#ArgumentError:wrongnumberofarguments(2for3)
Aynıkodukullandık,Lambdayeterliparametrealmadığıiçinhataverdi.
Proc'uBlock'açevirmekElimizdekiArrayelemanlarınınherbirinibirfonksiyonatabiitutsak?Dizininherelemanınıekranayazdıranbirşey?
items=["Bubir","buiki","buüç"]
print_each_element=lambda{|item|putsitem}
items.each(&print_each_element)
Buörnekteitems.each(&print_each_element)satırıProc'uBlock'açevirdiğimizyer.&işinsırrı.each'dengeleneleman,sankimethodçağırırgibiprint_each_elementepasediliyor,karşılayanda{}içindetanımlıkodbloğunuçalıştırıyor.
Kezaaynıişi;
items=["Bubir","buiki","buüç"]
defprint_each_element(item)
putsitem
end
items.each(&method(:print_each_element))
şeklindedeyapabilirdik!
ProcveLambda
49
ConditionalStatements(Koşullar)Verilenifadenindoğruyadayanlışolduğununtestiyapılır,akıştrueyadafalsedurumunagöreseyreder.
ifdurumuifa==bthendediğimizde,Eğer"a,b'yeeşittir"önermesidoğruysademişoluruz.
ifa!=bthendediğimizde,Eğer"a,b'yeeşitdeğildir"önermesidoğruysademişoluruz.
Aynımantıkta,a>b("a,b'denbüyüktür"),a<b("a,b'denküçüktür"),a>=b("a,b'enbüyükyadaeşittir"),a<=b("a,b'denküçükyadaeşitse")şeklindeönermelerdekurulabilir.
NegatiflikOperatörü!işaretiönermeninsoltarafındakullanılırsa,negatiflikyadaolumsuzlukkontrolüolduğuanlamındadır.
if!a==bthenputs"a,b'yeeşitdeğil"endyadaif!a>bthenputs"a,b'denbüyükdeğil"endgibikullanılır.İçeridekiönermenintersidoğruysademektir.
if!a==bthenörneğinidahaiyiinceleyecekolursak.Örnekteönerme"a,b'yeeşittir"önermesininolumsuzu,yani"a,b'yeeşitdeğildir"dir.Yanibuifdurumuşunakarşılıkgelmektedir:"a,b'yeeşitdeğildir"doğruise
ÇokluKontrolEğerönermelerarasındaand(ve),or(veya)yadabunlarınkısayollarını(andiçin&&,oriçin||)kullanırsakbirdenfazlaşeyikontroletmişoluruz.
a=5
b=10
ifa==5&&b==10
puts"İşlemedevamedebiliriz!"
end
ifa==5&&b==10yerineifa==5andb==10deyazabilirdik.
ConditionalStatements(Koşullar)
50
Ruby'ninkonuşmadilineyakınolmasısebebiyle,çokdahaanlaşılırkontrolsatırlarıyazmakmümkün.Örneğin,Eğer,a,5'eeşitseMerhabaYazdemekiçinilkaklagelenyöntem:
ifa==5
puts"Merhaba"
end
amabunuçokdahabasithalegetirebiliriz:
puts"Merhaba"ifa==5Teksatırda,ifikoşulsonucundaolacakşeyinsağınayazmakyeterlidir.
elsif
Programlamamantığındapekdesevmediğim(dahadüzgünyöntemlerivar)amabazenmecburkaldığımızbirdurumdur.
ifa==b
puts"a,b'yeeşit"
elsifa<b
puts"a,b'denküçük"
else
puts"a,b'tenbüyük"
end
İlkolaraka==bkontrolüyapılır,eğersonuçfalseise,a<bkontroledilir,odafalseiseensondakielsedevreyegiriyorveçıktıolarak"a,b'tenbüyük"yazdırılıyor.
unless
Bu,aslındaifintersigibi.Dahadoğrusuifnotanlamında.Eğera,b'yeeşitdeğilsedemekiçin;
unlessa==b
puts"Eşitdeğil"
end
Aynımantıktaputs"Eşitdeğil"unlessa==bşeklindedeyazabiliriz.Semantikolarakolumsuzlukkontrolüyaparkenunlesskullanılmasıönerilir.Koduokumaveanlamaaçısındankolayolmasıiçin.
while,break,untilDöngüleri
ConditionalStatements(Koşullar)
51
Tanımlananönermetrueolduğusüreceloopyanidöngüçalıştırmakontrolüdür.
i=0
whilei<5do
puts"i=#{i}"
i+=1
end
Eğeri+=1yaniiyibirarttır,demezseksonsuzdöngüyegireriz.Eğerbellibirandadöngüyükırmakistersek,
i=0
whilei<5do
puts"i=#{i}"
breakifi==3
i+=1
end
i3olduğundaloopdevredışıkalır...
Aynıunlessmantığında,untilkullanılırloop'larda.
i=0
untili==10do
puts"i=#{i}"
i+=1
end
Yanii10'aeşitolmadığısürecebuloopçalışır.
case,whenYapısıelsifyerinekullanılmasımuhtemel,dahaanlaşılırkontrolmekanizmasıdır.Hemenörneğebakalım:
computer="c64"
year=casecomputer
when"c64"then"1982"
when"c16"then"1984"
when"amiga"then"1985"
else
"Tarihbilinmiyor"
end
puts"#{computer}çıkışyılı#{year}"
#c64çıkışyılı1982
ConditionalStatements(Koşullar)
52
Yukarıdakikodubirtonif,elsifileyapmakyerine,whenvetheniledahaanlaşılırhalegetirdiğimizidüşünüyorum.
whenkullanırkenrange(aralık)belirmesideyapmaşansıvar.
student_grade=8
casestudent_grade
when0
puts"Çokkötü"
when1..4
puts"Başarısız"
when5..7
puts"İyi"
when8..9
puts"Çokİyi"
when10
puts"Süper"
end
Eğernot1ile4aralığındaysa(vedahilise)yada5ile7aralığındaysagibibirkontrolekledik.
forDöngüsü1'den10'akadar(1ve10dahil)birdöngüyapalım:
foriin1..10
puts"i=#{i}"
end
#i=1
#i=2
#i=3
#i=4
#i=5
#i=6
#i=7
#i=8
#i=9
#i=10
Aynıişiçokdahakolayyapmanınyolunu5.Bölüm'deIterationkısmındagöreceğiz!
TernaryOperatörüKısaltılmışifyapısıdır.Hemenhemenpekçokdildekullanılan,Eğerşudoğruisebudeğilsebuifadesiiçinkullanılır.
ConditionalStatements(Koşullar)
53
amount=2
pluralize=amount==1?"apple":"apples"
puts"#{amount}#{pluralize}."
BuörnekteTernaryolarakamount==1?"apple":"apples"kullanılmış,eğeramount1ise"apple"dönecek,değilise"apples"dönecek.Yanipluralizedeğişkeninekontroldendönenatanıyor.
BEGINveENDRuby'deilginçbirözellikde,kodunçalışmasındanönceyevesonrayabirektakabiliyoruz.
AşağıdakiörnekteBEGINblock'undakikodlarprogrambaşladığında,ENDblock'undakikodlarprogrambitmedenhemenönceçalışacaktır.
BEGIN{puts"Kodunbaşlamasaati#{Time.now.to_s}"}
END{puts"Kodunbitmesaati#{Time.now.to_s}"}
defsay_hello(username)
"Merhaba#{username}"
end
putssay_hello"Uğur"
sleep5#zamanfarkıiçin5saniyebekle
#Kodunbaşlamasaati2014-08-0409:30:24+0300
#MerhabaUğur
#Kodunbitmesaati2014-08-0409:30:29+0300
ConditionalStatements(Koşullar)
54
Bölüm4BubölümdeRuby'dekiveritipleriyaniDataTypes'ıinceleyeceğiz.
ObjectNumberStringArrayHashSymbolClassModule
Bölüm4
55
Object(Nesne)Ruby,ObjectOrientedProgramming'indibidir:)Herşeynesnelerdenoluşur.Nasılmı?hemenbasitbirdeğişkenoluşturupiçinebirtekstyazalım.
mesaj="Merhaba"
mesajdeğişkeninintürüne?
mesaj.class#=>String
BudeğişkenStringnesnesindentüremiş.Peki,Stringneredengeliyor?
mesaj.class.superclass#=>Object
Dikkatettiysenizburadasuperclasskullandık.Yanibuhiyerarşidekibirüstsınıfıarıyoruz.Karşımızaneçıktı?Object.PekiacabaObjectneredentüremiş?
mesaj.class.superclass.superclass#=>BasicObject
Hmmm..PekiBasicObjectneredengeliyor?
mesaj.class.superclass.superclass.superclass#=>nil
İşteşuandadibibulduk:)Demekkihiyerarşi;
BasicObject>Object>String
şeklindebirhiyerarşisözkonusu.
Peki,sayılardadurumne?
numara=1
numara.class#=>Fixnum
numara.class.superclass#=>Integer
numara.class.superclass.superclass#=>Numeric
numara.class.superclass.superclass.superclass#=>Object
numara.class.superclass.superclass.superclass.superclass#=>BasicObject
numara.class.superclass.superclass.superclass.superclass.superclass#=>nil
Object
56
Ufff...biraniçinbitmeyeceksandım:)Çokbasitbirsayıtanımlasıyaptığımızdabile,arkaplandakiişleyişyukarıdakigibioluyor.Yani
BasicObject>Object>Numeric>Integer>Fixnum
şeklindeyineananesneBasicObjectolmakkoşuluylauzunbirhiyerarşisözkonusu.
HerşeyBasicObjectdentürüyor,buyüzdendeaslındaherşeybirClassdolayısıylabudurumdileçokciddiesneklikkazandırıyor.
NesneMetodları(ObjectInstanceMethods)Şimdiboşbirnesneoluşturalım.Classbölümündedahadetaylıgöreceğimizinstantiateişlemiylenewmethodunukullanarak;
o=Object.new#=>#<Object:0x007fe552099a68>
o.__id__#=>70311450299700
yaptığımızda,oluşannesneninhafızadaunique(yanibundansadecebirtane)biridentifier'ı(kabacabunakimlikdiyelim)yaniID'siolduğunugörürüz.__id__yerineobject_idyanio.object_idşeklindedekullanabiliriz.
Eğerhashmethod’unuçağırırsak,RubybizeilgiliobjeninFixnumtüründesayısaldeğeriniüretirveverir.
o=Object.new#=>#<Object:0x007f8c3b0a3420>
o.__id__#=>70120131336720
o.object_id#=>70120131336720
o.hash#=>-229260864779029724
NeticedeStringdebirnesneve;
Object
57
t=String.new("Hello")#=>"Hello"
t.__id__#=>70170408456140
t.methods#=>[:<=>,:==,:===,:eql?,:hash,:casecmp,:+,:*,:%,:[
],:[]=,:insert,:length,:size,:bytesize,:empty?,:=~,:match,:succ,:succ!,:nex
t,:next!,:upto,:index,:rindex,:replace,:clear,:chr,:getbyte,:setbyte,:bytesl
ice,:scrub,:scrub!,:freeze,:to_i,:to_f,:to_s,:to_str,:inspect,:dump,:upcase,
:downcase,:capitalize,:swapcase,:upcase!,:downcase!,:capitalize!,:swapcase!,:h
ex,:oct,:split,:lines,:bytes,:chars,:codepoints,:reverse,:reverse!,:concat,:
<<,:prepend,:crypt,:intern,:to_sym,:ord,:include?,:start_with?,:end_with?,:sc
an,:ljust,:rjust,:center,:sub,:gsub,:chop,:chomp,:strip,:lstrip,:rstrip,:su
b!,:gsub!,:chop!,:chomp!,:strip!,:lstrip!,:rstrip!,:tr,:tr_s,:delete,:squeez
e,:count,:tr!,:tr_s!,:delete!,:squeeze!,:each_line,:each_byte,:each_char,:eac
h_codepoint,:sum,:slice,:slice!,:partition,:rpartition,:encoding,:force_encodin
g,:b,:valid_encoding?,:ascii_only?,:unpack,:encode,:encode!,:to_r,:to_c,:>,:
>=,:<,:<=,:between?,:nil?,:!~,:class,:singleton_class,:clone,:dup,:taint,:t
ainted?,:untaint,:untrust,:untrusted?,:trust,:frozen?,:methods,:singleton_metho
ds,:protected_methods,:private_methods,:public_methods,:instance_variables,:insta
nce_variable_get,:instance_variable_set,:instance_variable_defined?,:remove_instanc
e_variable,:instance_of?,:kind_of?,:is_a?,:tap,:send,:public_send,:respond_to?,
:extend,:display,:method,:public_method,:singleton_method,:define_singleton_meth
od,:object_id,:to_enum,:enum_for,:equal?,:!,:!=,:instance_eval,:instance_exec,
:__send__,:__id__]
t.method(:upcase).call#=>"HELLO"
t.methodsiseString'dentüreyentyeaittümmethod’larılisteledik.SonuçArray(Dizi)olarakgeldivebudizinintümelemanları:işaretiylebaşlıyor.ÇünkübuelemanlarbirerSymbol.
t.method(:upcase).calldaise,t'nin:upcasemethod’unucallileçağırdır.Aslındayaptığımıziş:"hello".upcaseilebirebiraynı.
Acababunesnene?
t.is_a?(String)#=>trueis_a?method’uilenesnenintürünükontroledebiliriz.
Diğerdillerinpekçoğunda(özelliklePython)birişiyapmanınbiryadaenfazlaikiyoluvarken,Rubybukonudaçokrahattır.Birişiyapmanınherzamanbirdenfazlayoluolurvebunlarınneredeysehepsidoğrudur.(Kullanıldığıyereveamacabağlıolarak)
is_a?yerinekind_of?dakullanabiliriz!
Birnesneyeaithangimethod'larınolduğunu;
Object
58
o=Object.new
o.methods#=>[:nil?,:===,:=~,:!~,:eql?,:hash,:<=>,:class,:singleton_class,:
clone,:dup,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:freeze,:fro
zen?,:to_s,:inspect,:methods,:singleton_methods,:protected_methods,:private_meth
ods,:public_methods,:instance_variables,:instance_variable_get,:instance_variable_
set,:instance_variable_defined?,:remove_instance_variable,:instance_of?,:kind_of?,
:is_a?,:tap,:send,:public_send,:respond_to?,:extend,:display,:method,:public_
method,:singleton_method,:define_singleton_method,:object_id,:to_enum,:enum_for,
:==,:equal?,:!,:!=,:instance_eval,:instance_exec,:__send__,:__id__]
o.public_methods#=>[:nil?,:===,:=~,:!~,:eql?,:hash,:<=>,:class,:singleton_c
lass,:clone,:dup,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:freez
e,:frozen?,:to_s,:inspect,:methods,:singleton_methods,:protected_methods,:priva
te_methods,:public_methods,:instance_variables,:instance_variable_get,:instance_va
riable_set,:instance_variable_defined?,:remove_instance_variable,:instance_of?,:ki
nd_of?,:is_a?,:tap,:send,:public_send,:respond_to?,:extend,:display,:method,:
public_method,:singleton_method,:define_singleton_method,:object_id,:to_enum,:enu
m_for,:==,:equal?,:!,:!=,:instance_eval,:instance_exec,:__send__,:__id__]
o.private_methods#=>[:initialize_copy,:initialize_dup,:initialize_clone,:sprintf
,:format,:Integer,:Float,:String,:Array,:Hash,:warn,:raise,:fail,:global_var
iables,:__method__,:__callee__,:__dir__,:eval,:local_variables,:iterator?,:bloc
k_given?,:catch,:throw,:loop,:respond_to_missing?,:trace_var,:untrace_var,:at_e
xit,:syscall,:open,:printf,:print,:putc,:puts,:gets,:readline,:select,:readl
ines,:`,:p,:test,:srand,:rand,:trap,:exec,:fork,:exit!,:system,:spawn,:sle
ep,:exit,:abort,:load,:require,:require_relative,:autoload,:autoload?,:proc,:
lambda,:binding,:caller,:caller_locations,:Rational,:Complex,:set_trace_func,:g
em,:gem_original_require,:initialize,:singleton_method_added,:singleton_method_rem
oved,:singleton_method_undefined,:method_missing]
o.protected_methods#=>[]
o.public_methods(false)#=>[]
public_methodsdefaultolarakpublic_methods(all=true)şeklindeçalışır.Eğerparametreolarakfalsegeçersekvebubizimoluşturduğumuzbirnesneise,sadeceilgilinesneninpublic_method'larıgeridöner.
Baştabelirttiğimizgibi,basitbirnesnebileObject'dentürediğiiçinvedefaultolarakbutüremeesnasındatümözelliklerdiğerinegeçtiğiiçin,sadecesizinmethod'larınızıgörüntülemekaçısındanfalseolayıçokişeyarar.
MethodMissingBenceRuby'ninensüperözelliklerindenbiridir.Olmayanbirmethod'uçağırdığınızzamantetiklenenmethodmethod_missingmethod'udur.RubyonRailsframework'üneredeysebumekanizmaüzerinekurulmuştur.3parametrealır;çağırılanmethod,eğerparametregeçilmişseparametreler,eğerblockgeçilmişseblock.
Object
59
classUser
defmethod_missing(method_name,*args,&block)
ifmethod_name==:show_user_info
"Thisuserhasnoinformation"
else
"You'vecalled#{method_name},You'vepassed:#{args}"
end
end
end
u=User.new
u.show_user_info#=>"Thisuserhasnoinformation"
u.show_user_age#=>"You'vecalledshow_user_age,You'vepassed:[]"
UseradındabirClass'ımızvar.İçindehiçbirmethodtanımlıdeğil.u.show_user_infosatırında,olmayanbirmethod'uçağırıyoruz.Tanımladığımızmethod_missingmethod'uileolmayanmethodçağırılmasınıyakalıyoruz.Eğershow_user_infodiyebirmethodçağrılırsayakalıyoruz,bunundışındabirşeyolursadamethodadınıvegeçilenparametrelerigösteriyoruz.
BusayedeNoMethodErrorhatasıalmadanişimizedevamedebiliyoruz.
Anlamakaçısından,Romanrakamlarıiçinbirsınıfyaptığınızıdüşünün.Sadeceörnekolmasıiçingösteriyorum,C,XveMiçin;
classRoman
defroman_to_str(str)
casestr
when"x","X"
10
when"c","C"
100
when"m","M"
1000
end
end
defmethod_missing(method)
roman_to_strmethod.id2name
end
end
r=Roman.new
r.x#=>10
r.X#=>10
r.C#=>100
r.M#=>1000
Bunugeliştirip"MMCX"yada"III"gibigerçekdönüştürmeişiniyapabilirsiniz.
respond_to_missing?
Object
60
Yukarıdakiörnekte,olmayanmethod'larıürettik.Peki,acababuolmayanmethod'larınasılçağırabiliryadakontroledebiliriz?Normalde,birClass'ınhangimethod'uolduğunurespond_to?ileöğreniyorduk.Örneğeuygulayalım;
r.Cderkenaslında:Cmethod'unuçağırıyoruz.Pekiböylebirmethodvarmı?
r.method(:C)#=>`method':undefinedmethod`C'forclass`Roman'(NameError)
Nasılyani?pekikontroledelim?
r.respond_to?(:C)#=>false
Çünkübiz:Cyidinamikolarakürettikamaöyleceortadabıraktık.Yapmamızgerekenrespond_to_missing?ilegerekencevabıvermekti:
classRoman
defroman_to_str(str)
casestr
when"x","X"
10
when"c","C"
100
when"m","M"
1000
end
end
defmethod_missing(method)
roman_to_strmethod.id2name
end
defrespond_to_missing?(method_name,include_private=false)
[:x,:X,:c,:C,:m,:M].include?(method_name)||super
end
end
r.method(:C)#=>#<Method:Roman#C>
r.respond_to?(:C)#=>true
r.respond_to?(:Q)#=>false#olmayanmethod
Object
61
Number(Sayılar)Sayılar,temelöğeolmayıp,direknesnedentüremişlerdir.TürediklerinesnedeRuby'ninsayılariçinolanbaseclass'ıdır.
Örneğin3sayısınabakalım:
3.class#=>Fixnum
3.class.superclass#=>Integer
3.class.superclass.superclass#=>Numeric
3.class.superclass.superclass.superclass#=>Object
Numericsınıfıdırasılolan.İlktürediğisınıfıFixnumdır.Örnektegördüğünüzgibi;
Fixnum>Integer>Numericşeklindebirhiyeraşisözkonusudur.
2014.class#=>Fixnum
2_014.class#=>Fixnum
201.4.class#=>Float
1.2e3.class#=>Float
7e4.class#=>Float
7E-4.class#=>Float
0664.class#=>Fixnum
0xfff.class#=>Fixnum
0b1111.class#=>Fixnum
45678327041234321312.class#=>Bignum
Ruby'desayıişlerinde_hiçbiretkiyapmaz.Birşekildeokumayıkolaylaştırmakiçinkullanılır.Örnekteki2014ile2_014aynışeydir.Büyüksayılarıyazarken;1_345_201gibibirifade1345201'diraslında.
Ondalıksayılarda.kullanılır.Octalyani8'liksayısistemiiçindirek0ile0664gibikullanılır.16'lıkyaniHexadecimalsayısistemiiçin,cssdünyasındantanıdığınızbeyazrenginiifadeetmekiçin$fffyerine0xfffşeklindebirkullanımmevcut.2'likyaniBinarysayısistemiiçin0bilebaşlamakyeterlidir.ScientificNotationifadeleriiçinde1.2e3yada7e4gibikullanımlarmümkündür.
NumberMethod'ları5sayısıFixnumsınıfındandırveneticedeüstsınıfları;
Numeric->Integer->Fixnum
Number
62
şeklindeolduğuiçin(enüsttteNumeric)ilgiliüstsınıflarınmethod'larıdaFixnumtarafındankullanılabilirdurumdadır.
Herzamankigibi,acababusınıfaaitmethodlarneymiş?dediğimizanbirtonmethodgelirkarşımıza;
5.methods#=>[:to_s,:inspect,:-@,:+,:-,:*,:/,:div,:%,:modulo,:divmod,:fdi
v,:**,:abs,:magnitude,:==,:===,:<=>,:>,:>=,:<,:<=,:~,:&,:|,:^,:[],:<<,
:>>,:to_f,:size,:bit_length,:zero?,:odd?,:even?,:succ,:integer?,:upto,:down
to,:times,:next,:pred,:chr,:ord,:to_i,:to_int,:floor,:ceil,:truncate,:round
,:gcd,:lcm,:gcdlcm,:numerator,:denominator,:to_r,:rationalize,:singleton_metho
d_added,:coerce,:i,:+@,:eql?,:remainder,:real?,:nonzero?,:step,:quo,:to_c,:
real,:imaginary,:imag,:abs2,:arg,:angle,:phase,:rectangular,:rect,:polar,:co
njugate,:conj,:between?,:nil?,:=~,:!~,:hash,:class,:singleton_class,:clone,:
dup,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:freeze,:frozen?,:m
ethods,:singleton_methods,:protected_methods,:private_methods,:public_methods,:in
stance_variables,:instance_variable_get,:instance_variable_set,:instance_variable_d
efined?,:remove_instance_variable,:instance_of?,:kind_of?,:is_a?,:tap,:send,:pu
blic_send,:respond_to?,:extend,:display,:method,:public_method,:singleton_method
,:define_singleton_method,:object_id,:to_enum,:enum_for,:equal?,:!,:!=,:instan
ce_eval,:instance_exec,:__send__,:__id__]
Bunlarıniçindenensıkkullanılanlaravekullanımşekillerinedeğineceğim.
Number
63
5.to_s#=>"5"
#SayısaldeğeriString'eçevirdik
-5.abs#=>5
#Mutlakdeğer
5.zero?#=>false
#Sıfırmı?
5.even?#=>false
#Çiftsayımı?
5.odd?#=>true
#Teksayımı?
5.next#=>6
#Sonrakisayı?
5.pred#=>4
#Öncekisayı?
3.14.floor#=>3
#Tabandeğeri
3.14.ceil#=>4
#Tavandeğeri
1.49.round#=>1
1.51.round#=>2
#Yuvarlama
1.bit_length#=>1
15.bit_length#=>4
255.bit_length#=>8
#Bitcinsindenuzunluğu/boyu
1.size#=>8
10.size#=>8
10242048.size#=>8
1024204810242048102420481024.size#=>12
#Bytecinsindenkapladığıyer
upto,downtogibiiterasyonlailgiliolanlarıEnumerationveIterationbölümündegöreceğiz!
Number
64
StringKabaca,insanlarınanlayacağışekildetekst/metinbilgisiiçerennesnelerdir.Örneğin;
m="Merhaba"
m.class#=>String
şeklindedir.Tanımlamayaparkentekyadaçifttırnakkullanılabiliramaaralarındafarkvardır.ExpressionSubstitutionyadaStringInterpolationolarakgeçen,Stringiçindedeğişkenkullanımıesnasındaçifttırnakkullanmanızgerekir.
m="Merhaba"
puts"#{m}Uğur"#MerhabaUğur
puts'#{m}Uğur'##{m}Uğur
Tektırnakkullandığımızörnekte#{m}değişkeniişlenmedenolduğugibiçıktıvermiştir.Aynışekildeescapecodesyanigörünmeyenözelkarakterleridesadeceçifttırnakiçindekullanmakmümkündür.
Çifttırnakiçindekullanılan#{BURAYARUBYKODUGELİR}çokişeyarar.{ve}arasındakodçalıştırmamızısağlar.
puts"Saat:#{Time.now}"#Saat:2014-08-1210:37:22+0300
dediğimizde;RubyKernel'danTimenesnesininnowmethod'unuçalıştırmışoluruz.
puts"Merhaba\nDünya"
#Merhaba
#Dünya
\nNewLineyadaLineFeedyadayenisatırageçmekarakteriçifttırnaktaçalışır.
String
65
EscapeKod Anlamı
\n Yenisatır(0x0a)
\s Boşluk(0x20)
\r SatırBaşı(0x0d)
\t TabKarakteri(0x09)
\v DikeyTab(0x0b)
\f Formfeed(0x0c)
\b Backspace(Birgeri)(0x08)
\a Bell/Alert(Uyarı)(0x07)
\e Escape(0x1b)
\nnn Octal,8'likdeğer
\xnn Hexadecimal,16'lıkdeğer
\unnnn Unicode:U+nnnn(Ruby1.9+)
\cx Control-x
\C-x Control-x
\M-x Meta-x
\M-\C-x Meta-Control-x
\x x'inkendisi(\"çifttırnakdemektir.)
String'lerbytearray'lerdenoluşuryanielemanlarıbytecinsindendizidiraslında.
m=""
m<<65
putsm#A
mboşbirString,diziyeelemaneklergibi(<<diziyeelemanekler,azsonragöreceğiz)içine65ekledik.BuAharfinin10'luksayısistemindekiASCIIdeğeridir.Aslındam="A"yaptık:)
Eğer65inkaraktersetindekideğerineydi?dersekput65.chryaptığımızdabizeAdöner.0ile255arasıdeğerlerdirbunlar.
Dahailginçbirolay;
puts"öz""yıl""maz""el"#özyılmazel
yani"tekst""tekst""tekst"şekindebirkullanımmevcuttur.
String
66
StringLiterals(StringKalıpları)Ruby'de,yinediğerdillerdeolmayanilginçbirözellik.%işaretivesonrasındagelenbazıkarakterleryardımıylaenteresanşeyleryapmakmümkün:
%
Süslüparantezlerarasındakalanherşeyconcat(yanitoplanarak)edilirveStringolarakçıktıverirvetırnaklarıescapeeder.
%{MerhabaDünyaBenvigonasılsınız?}#=>"MerhabaDünyaBenvigonasılsınız?"
%{Buişlemlerin%80'i"uydurma"}#=>"Buişlemlerin%80'i\"uydurma\""
aynıişi;%|MerhabaDünyaBenvigonasılsınız?|süslüparantezyerinepipe|kullanarakdayapabilirsiniz!
%w
HızlıcaArrayüretmeyisağlar:
%w{foobarbaz}#=>["foo","bar","baz"]
%w{foobarbaz}.class#=>Array
%i
İçindeSymbololanArrayüretir:
%i{foobarbaz}#=>[:foo,:bar,:baz]
%qve%Q
qtektırnak,Qçifttırnaklasarmalamışgibiyapar:
person="Uğur"
%q{Merhaba#{person}}#=>"Merhaba\#{person}"
%Q{Merhaba#{person}}#=>"MerhabaUğur"
%s
Symbol'eçevirir:
String
67
%s{my_variable}#=>:my_variable
%s{email}#=>:email
%r
RegularExpression'açevirir:
%r{(.*)hello}i#=>/(.*)hello/i
%x
Ruby'debacktickkullanarakshellkomutuçalıştırabilirsiniz.YaniLinuxveMackullananokuyucularTerminalilehaşır-neşirolmuşlardır.Örneğin,bulunduğunuzdizindekidosyalistesinialmakiçinlskomutunukullanırsınız.Örneğinkendihomedizinimdelsyaptığımda(OSXkullanıyorum)
ls-1#altaltalistemelekiçin
Applications
Desktop
Development
Documents
Dotfiles
Downloads
Library
VirtualBoxVMs
Works
bin
gibibirlistealıyorum.YapacağımbirRubyuygulamasında;
%x{ls-1$HOME}#=>"Applications\nDesktop\nDevelopment\nDocuments\nDotfiles\nDownloa
ds\nLibrary\nVirtualBoxVMs\nWorks\nbin\n"
TümlistetekbirStringolarakgeldive\nkarakteriilebirleştiçünkisonuçaltaltasatırsatırgeldi.Eğer;
%x{ls-1$HOME}.split("\n")
deseydimsonuçbanadiziolarakgelecekti!
String
68
#["Applications","Desktop","Development","Documents","Dotfiles","Downloads","Li
brary","VirtualBoxVMs","Works","bin"]
%x{ruby--copyright}#=>"ruby-Copyright(C)1993-2014YukihiroMatsumoto\n"
HereDocumentKullanımıUzunmetinkullanımlarındaçokişeyarar:
mesaj=<<END
Merhabanasılsınız?
Bizdeçokiyiyiz
Görüşürüz!
END
putsmesaj
#Merhabanasılsınız?
#Bizdeçokiyiyiz
#Görüşürüz!
Buörnektemesaj=<<ENDileENDkelimesinigörenekadariçindenevarsakullandiyoruz!Dahadaçılgınbirkullanımşekli;
mesaj=[<<BİR,<<İKİ,<<ÜÇ]
BuBir
BİR
Buiki....
İKİ
Budaüüüüüüüüç
ÜÇ
putsmesaj
#-BuBir
#-Buiki....
#-Budaüüüüüüüüç
StringMethod'ları
String%argüman->yeniString
"Merhaba%s"%"Uğur"#=>"MerhabaUğur"
"Sayı:%010d"%2014#=>"Sayı:0000002014"
"KullanıcıAdı:%s,E-Posta:%s"%["vigo","[email protected]"]#=>"KullanıcıAdı:vig
o,E-Posta:[email protected]"
"Merhaba%{username}!"%{:username=>'vigo'}#=>"Merhabavigo!"
String
69
Kezabumethod,printf,sprintfgibi,StringFormatmantığındaçalışır."Sayı:%010d"%2014örneğinde%010daslında10basamaklı,0ilepadedilmişşekildegösteranlamındadır.20144basamaklıdır,solunda6tanesıfırgelmiştir.
String*sayı->yeniString
Stringilesayıyıçarpmakmümkün!
"Merhaba!"*3#=>"Merhaba!Merhaba!Merhaba!"
"Merhaba!"*0#=>""
String+String->yeniString
"Merhaba"+""+"Dünya"#=>"MerhabaDünya"
String<<sayı->String
String<<nesne->String
a="Merhaba"
a<<"dünya"#=>"Merhabadünya"
a#=>"Merhabadünya"
a.concat(33)#=>"Merhabadünya!"
a<<33#=>"Merhabadünya!!"
String<=>başkastring→-1,0,+1yadanil
<=>RubydünyasındaSpaceshipoperatörüolarakgeçer.Aynıcinsnesnelerikarşılaştırmakiçinkullanılır.
"vigo"<=>"vigo"#=>0#eşit
"vigo"<=>"vig"#=>1#vigobüyük
"vigo"<=>"vigoo"#=>-1#vigoküçük
"vigo"<=>3#=>nil#alakasızikişey
casecmpileaynıişiyapar
String=~Nesne->Fixnumyadanil
String
70
"Saattam4'debuluşalım"=~/\d/#=>9
#\dsayıyakaladıveindeksidöndü
"Saattam4'debuluşalım"[9]#=>"4"
Stringiçindehareket
Stringaslındakarakterlerdenoluşanbirdiziolduğuiçinaşağıdakigibiatraksiyonlaryapmakmümkün.
String[indeks]->yenistringyadanil
String[başlangıç,uzunluk]->yenistringyadanil
String[range]->yenistringyadanil
String[regexp]->yenistringyadanil
String[regexp,yakalan]->yenistringyadanil
String[metinni_bul]->yenistringyadanil
örnekolarak;
m="MerhabaDünya"
m[0]#=>"M"#0.karakter
m[0,2]#=>"Me"#0'danitibaren2karakter
m[0..4]#=>"Merha"#range,0'dan4dahil
m[-1,]#=>"a"#sonkarakter
m[-13..-1]#=>"MerhabaDünya"#sondanbaşa
m[15,1]#=>nil#olmayanindeks
m[/(?<sesli>[aeiou])/,"sesli"]#=>"e"#regexp
m["Merhaba"]#=>"Merhaba"#metnibul
m["vigo"]#=>nil#olmayanmetin
aynıişisliceiledeyapabilirsiniz.
m="merhaba"
m.slice(2,5)#=>"rhaba"
gibi...
YardımcıMethodlar
Sıkçakullanılanlararasında;capitalize,center,chars,chomp,chop,clear,count,size,length,delete,ljust,rjust,reverse,upcase,downcase,swapcase,reverse,index,hex,rindex,insertgibimethodlar'danörneklerekledim.Herzamanolduğugibi,hangimethod'larınolduğunugörmekiçin;
String
71
String.new.methods#=>[:<=>,:==,:===,:eql?,:hash,:casecmp,:+,:*,:%,:[],:[]
=,:insert,:length,:size,:bytesize,:empty?,:=~,:match,:succ,:succ!,:next,:ne
xt!,:upto,:index,:rindex,:replace,:clear,:chr,:getbyte,:setbyte,:byteslice,:
scrub,:scrub!,:freeze,:to_i,:to_f,:to_s,:to_str,:inspect,:dump,:upcase,:down
case,:capitalize,:swapcase,:upcase!,:downcase!,:capitalize!,:swapcase!,:hex,:o
ct,:split,:lines,:bytes,:chars,:codepoints,:reverse,:reverse!,:concat,:<<,:p
repend,:crypt,:intern,:to_sym,:ord,:include?,:start_with?,:end_with?,:scan,:l
just,:rjust,:center,:sub,:gsub,:chop,:chomp,:strip,:lstrip,:rstrip,:sub!,:g
sub!,:chop!,:chomp!,:strip!,:lstrip!,:rstrip!,:tr,:tr_s,:delete,:squeeze,:co
unt,:tr!,:tr_s!,:delete!,:squeeze!,:each_line,:each_byte,:each_char,:each_code
point,:sum,:slice,:slice!,:partition,:rpartition,:encoding,:force_encoding,:b,
:valid_encoding?,:ascii_only?,:unpack,:encode,:encode!,:to_r,:to_c,:>,:>=,:<
,:<=,:between?,:nil?,:!~,:class,:singleton_class,:clone,:dup,:taint,:tainted
?,:untaint,:untrust,:untrusted?,:trust,:frozen?,:methods,:singleton_methods,:p
rotected_methods,:private_methods,:public_methods,:instance_variables,:instance_va
riable_get,:instance_variable_set,:instance_variable_defined?,:remove_instance_vari
able,:instance_of?,:kind_of?,:is_a?,:tap,:send,:public_send,:respond_to?,:exte
nd,:display,:method,:public_method,:singleton_method,:define_singleton_method,:o
bject_id,:to_enum,:enum_for,:equal?,:!,:!=,:instance_eval,:instance_exec,:__se
nd__,:__id__]
kullanabiliriz!
m="merhaba"
m.capitalize#=>"Merhaba"
m#=>"merhaba"
m.capitalize!#=>"Merhaba"#m'indeğeriartıkdeğişti!
m#=>"Merhaba"
"vigo".center(12)#=>"vigo"
"vigo".center(12,"*")#=>"****vigo****"
"merhaba".chars#=>["m","e","r","h","a","b","a"]
"merhaba\n".chomp#=>"merhaba"
"merhabadünya".chomp("dünya")#=>"merhaba"
"merhabavigo".chop#=>"merhabavig"
"merhabavigo\n".chomp#=>"merhabavigo"
"a".chr#=>"a"
x="Merhaba"
x.clear#=>""
"MerhabaDünya".count("a")#=>3#3adeta
"MerhabaDünya".count("ab")#=>4#avebtoplam4tane
"MerhabaDünya".count("e")#=>1#e'den1tane
"MerhabaDünya".delete("e")#=>"MrhabaDünya"
"MerhabaDünya".delete("a","ba")#=>"MerhbDüny"
String
72
"MERHABA".downcase#=>"merhaba"
"merhaba".upcase#=>"MERHABA"
"Merhaba".swapcase#=>"mERHABA"
"merhaba".size#=>7
"merhaba".length#=>7
"merhaba".ljust(20)#=>"merhaba"
"merhaba".ljust(20,"*")#=>"merhaba*************"
"merhaba".rjust(20)#=>"merhaba"
"merhaba".rjust(20,"*")#=>"*************merhaba"
"merhaba".strip#=>"merhaba"
"merhaba".lstrip#=>"merhaba"
"merhaba".rstrip#=>"merhaba"
"merhaba".index("m")#=>0
"merhaba".index("ba")#=>5
"merhaba".rindex("m")#=>0
"merhaba".rindex("h")#=>3
"a".next#=>"b"
"abcd".next#=>"abce"#d'densonraegeldi...
"b".succ#=>"c"
#baş,ayraç,son
"merhaba".partition("r")#=>["me","r","haba"]
"merhaba".partition("a")#=>["merh","a","ba"]
"merhaba".partition("x")#=>["","","merhaba"]
"merhabadünya".reverse#=>"aynüdabahrem"
"heyseeeeeeeeeeeeeeen!aloooooooo".squeeze#=>"heysen!alo"
"Merhaba".dump#=>"\"Merhaba\""
"merhaba".getbyte(0)#=>109#m'inasciideğeri
"0x0f".hex#=>15
"0x0fff".hex#=>4095
"merhaba".insert(0,"X")#=>"Xmerhaba"
"merhaba".insert(3,"A")#=>"merAhaba"
"merhaba".insert(-1,".")#=>"merhaba."
"123".oct#=>83#Octal'eçevirdi(8'lik)
"A".ord#=>65#Asciideğeri
"a".ord#=>97#Asciideğeri
"dünya".prepend("Merhaba")#=>"Merhabadünya"#öneekledi
#transform
"merhabahello".tr("el","ip")#=>"mirhabahippo"#e=>i,l=>poldu
"ArkAdAşlarnasılsınız?".tr("A","a")#=>"arkadaşlarnasılsınız?"
String
73
#a'dane'ykadarXiletransformyap
"merhabadünya".tr("a-e","X")#=>"mXrhXXXXünyX"
ConvertMethod'ları
Tipdeğiştirmekiçinkullanılır.to_i,to_f,to_s,to_str,to_sym,to_r,to_c,to_enummethod'larınabakalım:
"merhaba".to_i#=>0#integer'açevirdi
"merhaba".to_f#=>0.0#float'açevirdi
"5".to_i#=>5
"1.5".to_f#=>1.5
"merhaba".to_s#=>"merhaba"#string
"merhaba".to_str#=>"merhaba"#string
"merhaba".to_sym#=>:merhaba#symbol
"merhaba".to_r#=>(0/1)#Rasyonelsayı
"0.2".to_r#=>(1/5)#Rasyonelsayı
"merhaba".to_c#=>(0+0i)#Komplekssayı
"1234".to_c#=>(1234+0i)
"merhaba".to_enum#=>#<Enumerator:"merhaba":each>#Enumeratör'eçevirdi
KontrolMethod'ları
Methodadı?ilenbitiyordemek,birkontrololduğuvesonucunBooleanyanıtrueyadafalsedöndüğüanlamındaolduğunusöylemiştik.
"merhaba".start_with?("m")#=>true
"merhaba".start_with?("mer")#=>true
"merhaba".start_with?("f")#=>false
"merhaba".end_with?("a")#=>true
"merhaba".end_with?("haba")#=>true
"merhaba".end_with?("zoo")#=>false
"merhaba".eql?("Merhaba")#=>false
"merhaba".eql?("merhaba")#=>true
"merhabadünya".include?("dünya")#=>true
"merhaba".empty?#=>false
"".empty?#=>true
"kedi".between?("at","balık")#=>false#başlangıçharfiavebarasındamı?gibidü
şünün
"kedi".between?("fare","sinek")#=>true
ArrayveBlockileİlişkiliMethodlar
splitMetniparçalaraböler,varsayılandelimiter(ayırıcı)boşukkarakteridir.
String
74
"Selammilletnasılsınız?".split#=>["Selam","millet","nasıl","sınız?"]
"Selammillet-nasılsınız?".split("-")#=>["Selammillet","nasılsınız?"]
"Atakımı:65Btakımı:120".split(/+\d+?/)#=>["Atakımı:","Btakımı:"]
"1,2,3,4,5".split(",")#=>["1","2","3","4","5"]
each_byte
"merhaba".each_byte{|c|putsc}
#109(m)
#101(e)
#114(r)
#104(h)
#97(a)
#98(b)
#97(a)
each_char
"merhaba".each_char{|c|putsc}
#m
#e
#r
#h
#a
#b
#a
each_line
"Merhaba\nDünya\nNasılsın?".each_line{|l|putsl}
#Merhaba
#Dünya
#Nasılsın?
"Merhaba@@Dünya@@Nasılsın?".each_line("@@"){|l|putsl}
#Merhaba@@
#Dünya@@
#Nasılsın?
upto
String
75
"a1".upto("b1"){|t|putst}
#a1
#a2
#a3
#a4
#a5
#a6
#a7
#a8
#a9
#b0
#b1
PatternYakalama(Regexp)
Dahakapsamlıolarak6.Bölüm'dededeğineceğimizRegularExpressionkonusu,String'lerleçokilişkili.Hemenilgilimethod'larabakalım
gsubvesub
subilegsubarasındakifark,subilkbulduğunuişler,gsubGlobalanlamındadır.
"merhabadünya,merhabauzay".sub("merhaba","olaa")#=>"olaadünya,merhabauzay"
"merhabadünya,merhabauzay".gsub("merhaba","olaa")#=>"olaadünya,olaauzay"
"MerhabaDünya".gsub(/[aeiou]/,"x")#=>"MxrhxbxDünyx"
"MerhabaDünya".gsub(/([aeiou])/,'(\1)')#=>"M(e)rh(a)b(a)Düny(a)"
"Merhabadünya,merhabauzay,merhabaevren".gsub(/((m|M)erhaba)/){|c|c.upcase}#=>
"MERHABAdünya,MERHABAuzay,MERHABAevren"
"MerhabaDünya".gsub(/(?<sesli_harf>[aeiou])/,'{\k<sesli_harf>}')#=>"M{e}rh{a}b{a}
Düny{a}"
"MerhabaDünya".gsub(/[ea]/,'e'=>1,'a'=>'X')#=>"M1rhXbXDünyX"
match
"merhaba".match("a")#=>#<MatchData"a">
"merhaba".match("(a)")#=>#<MatchData"a"1:"a">#1taneyakaladı,(a)veArraygel
di
"merhaba".match("(a)")[0]#=>"a"#yakalanan
"merhaba2014".match(/\d/)#=>#<MatchData"2">
"merhaba2014".match(/(\d)/)#=>#<MatchData"2"1:"2">
"merhaba2014".match(/(\d+)/)#=>#<MatchData"2014"1:"2014">
"merhaba2014".match(/(\d+)/)[0]#=>"2014"
"merhaba2014".match(/(\d+)/)[0].to_i#=>2014
String
76
scan
Matchgibi,metinüzerindebirneviaramayapıyoruz:
"Merhabamillet!".scan(/\w+/)#=>["Merhaba","millet"]
"Merhabamillet!".scan(/./)#=>["M","e","r","h","a","b","a","","m","i","l
","l","e","t","!"]
"Merhabamillet!Saat10'dabuluşalım".scan(/Saat\d+/)#=>["Saat10"]
String
77
ArrayKompakt,sıralıobjeleriçerenbirtürütaşıcıyınesnedirArray'ler.NeredeyseiçindehertürRubyobjesinitaşıyabilir.(String,Integer,Fixnum,Hash,SymbolhattabaşkaArray'lervs...)
Arkaarkayasıralanmışkutucuklardüşünün,herkutucuğunbirindexnumarasıolduğunuhayaledin.Buindekslemeişiotomatikolarakoluyor.Diziyeherelemaneklediğinizde(Eğerkendinizindeksnumarasıatamadıysanız)yeniindeksbirartarakdevamediyor.ZeroIndexedyaniilkeleman0.elemanoluyor.
AynıString'dekigibinegatifindeksdeğerleriileterstenerişimsağlıyorsunuz.Yaniilkelemanarray[0]vesonelemanarray[-1]gibi...
Arrayoluşturmakiçin;
a=[]#Yabuşekilde
a.class#=>Array
b=Array.new#=>Yadabuşekilde
b.class#=>Array
kullanabilirsiniz.Kezaa=[1,2,3]dediğinizdedeArray'ihemtanımlamışhemdeelemanlarınıbelirlemişolursunuz.
Array'iinitializeederkenyaniilkkezoluştururkenbüyüklüğünüdeverebilirsiniz.
a=Array.new(5)#içinde5elemantaşıyacakArrayoluştur
a#=>[nil,nil,nil,nil,nil]
Hatta,defaultdeğerbileatarsınız:
aylar=Array.new(12,"ay")#12elemanolsunvehepsi"ay"olsun
aylar#=>["ay","ay","ay","ay","ay","ay","ay","ay","ay","ay","ay","ay"]
Ruby'dehernesneninbirID'siveHASHdeğerivardır.
[1,2,3].hash#=>3384159031637530117
[1,2,3].__id__#=>70147646473880
Blockkabulettiğiiçin;
Array
78
dizi=Array.new(10){|eleman|eleman=eleman*4}
dizi#=>[0,4,8,12,16,20,24,28,32,36]
#yadaaynıkodu
dizi=Array.new(10)do|eleman|
eleman=eleman*4
end
dizi#=>[0,4,8,12,16,20,24,28,32,36]
şeklindedekullanabilirsiniz.NeticedeArray'ininitializemethod'unaparametregeçmişoluyoruz:
aylar=Array.[]("oca","şub","mar","nis","may","haz","tem","ağu","eyl","eki",
"kas","ara")
aylar#=>["oca","şub","mar","nis","may","haz","tem","ağu","eyl","eki","kas
","ara"]
Yani:aylar=Array.[](param,param,param)gibi.
Başkanasılüretiriz?Sayılardanoluşanbirdizilazımolsa;Örneğin1984ile2000arasındakiyıllarlazımolsa;
years=Array(1984..2000)
years#=>[1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,19
96,1997,1998,1999,2000]
BirArrayiçindefarklıtürdenelemanlarolabilir;
a=["Hello",:word,2014,3.14]#içindeString,Symbol,FixnumveFloatvar!
a#=>["Hello",:word,2014,3.14]
Arrayiçindekielemanlarsıralıbirşekildedururlar.BusırayaIndexdenir.0'danbaşlar.YaniilkelemandemekArray'in0.elemanıdemektir.İsteğimizelemanıalmakiçinyaArray[index]yadaArray.fetch(index)yöntemlerinikullanabiliriz.
a=["Uğur","Yeşim","Ezel","Ömer"]
a[0]#=>"Uğur"
a.fetch(0)#=>"Uğur"
a[4]#=>nil
a.fetch(4,"HatalıIndex")#=>"HatalıIndex"
a=[1,2,3,4]#İlkNelemanıal
a.take(2)#=>[1,2]
a.drop(2)#=>[3,4]#take'intersi...İlk2haricinial
Array
79
Örnektea[4]dediğimizzaman,olmayanindex'lielemanıalmayaçalışıyorveelemanolmadığıiçinnilgerialıyoruz.fetchkullanarakhatakontrolüdeyapmışoluyoruz.nilyerinebelirlediğimizhatamesajınıdönmüşoluyoruz.
values_atmethod'uileilgiliindexyadaindex'lerdekielemanlarıalabiliriz,kezaatdebenzerişeyarar.
isimler=["Uğur","Ömer","Yeşim","Ezel","Eren"]
isimler.values_at(0)#=>["Uğur"]
isimler.values_at(1,2)#=>["Ömer","Yeşim"]
["a","b","c","d","e"].at(1)#=>"b"
["a","b","c","d","e"].at(-1)#=>"e"
rindexilesağdanhizalıindex'egöreelemanaulaşıyoruz:
a=["a","b","b","b","c"]
a.rindex("b")#=>3#3tanebvar,ensağdakisonb'yiverdi!
a.rindex("z")#=>nil
Keza"acabaArray'innegibimethod'larıvar?"dersek;hemenmethodsözelliğiilebakabiliriz.Karıştırmamamızgerekenönemlibirkonuvar.DetayınıClasskonusundagöreceğizamayerigelmişken,Array'inClassMethod'larıveInstanceMethod'larıvar.
Array.methodsdediğimizdeKernel'dangelenArrayobjesininyaniClass'ınınmethod'larınıgörürüz.EğerArray.new.methodsdersek,Array'dentürettiğimizinstance'aaitmethod'larıgörürüz.
Yania=[]dediğimizde,aslındaArray'denbirinstanceçıkartmışoluyoruz.AzönceArray.[](...)olarakyaptığımızşeydeaslındaClassmethod'uçağırmak.
ClassMethod'ları
Array
80
Array.methods#=>[:[],:try_convert,:allocate,:new,:superclass,:freeze,:===,:=
=,:<=>,:<,:<=,:>,:>=,:to_s,:inspect,:included_modules,:include?,:name,:ance
stors,:instance_methods,:public_instance_methods,:protected_instance_methods,:priv
ate_instance_methods,:constants,:const_get,:const_set,:const_defined?,:const_miss
ing,:class_variables,:remove_class_variable,:class_variable_get,:class_variable_se
t,:class_variable_defined?,:public_constant,:private_constant,:singleton_class?,:
include,:prepend,:module_exec,:class_exec,:module_eval,:class_eval,:method_defin
ed?,:public_method_defined?,:private_method_defined?,:protected_method_defined?,:p
ublic_class_method,:private_class_method,:autoload,:autoload?,:instance_method,:p
ublic_instance_method,:nil?,:=~,:!~,:eql?,:hash,:class,:singleton_class,:clone
,:dup,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:frozen?,:methods
,:singleton_methods,:protected_methods,:private_methods,:public_methods,:instance
_variables,:instance_variable_get,:instance_variable_set,:instance_variable_defined
?,:remove_instance_variable,:instance_of?,:kind_of?,:is_a?,:tap,:send,:public_s
end,:respond_to?,:extend,:display,:method,:public_method,:singleton_method,:def
ine_singleton_method,:object_id,:to_enum,:enum_for,:equal?,:!,:!=,:instance_eva
l,:instance_exec,:__send__,:__id__]
Bumethod'larınbirkısmıEnumerablesınıfındangelenmethod'lardır.Ruby,Moduleyapısıkullandığıiçinortakkullanılanmethod'larmodüleklemelerindengelmektedir.Classkonusundadetaylarıgöreceğiz.
Bukısımdanenfazlakullanacağımız[]venewmethod'larıolacaktır.
InstanceMethod'larıEnçokkullanacağımızmethod'larsa;
Array.new.methods#=>[:inspect,:to_s,:to_a,:to_h,:to_ary,:frozen?,:==,:eql?,
:hash,:[],:[]=,:at,:fetch,:first,:last,:concat,:<<,:push,:pop,:shift,:unsh
ift,:insert,:each,:each_index,:reverse_each,:length,:size,:empty?,:find_index,
:index,:rindex,:join,:reverse,:reverse!,:rotate,:rotate!,:sort,:sort!,:sort_
by!,:collect,:collect!,:map,:map!,:select,:select!,:keep_if,:values_at,:delet
e,:delete_at,:delete_if,:reject,:reject!,:zip,:transpose,:replace,:clear,:fil
l,:include?,:<=>,:slice,:slice!,:assoc,:rassoc,:+,:*,:-,:&,:|,:uniq,:uniq
!,:compact,:compact!,:flatten,:flatten!,:count,:shuffle!,:shuffle,:sample,:cy
cle,:permutation,:combination,:repeated_permutation,:repeated_combination,:produc
t,:take,:take_while,:drop,:drop_while,:bsearch,:pack,:entries,:sort_by,:grep,
:find,:detect,:find_all,:flat_map,:collect_concat,:inject,:reduce,:partition,
:group_by,:all?,:any?,:one?,:none?,:min,:max,:minmax,:min_by,:max_by,:minmax
_by,:member?,:each_with_index,:each_entry,:each_slice,:each_cons,:each_with_obje
ct,:chunk,:slice_before,:lazy,:nil?,:===,:=~,:!~,:class,:singleton_class,:cl
one,:dup,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:freeze,:metho
ds,:singleton_methods,:protected_methods,:private_methods,:public_methods,:instan
ce_variables,:instance_variable_get,:instance_variable_set,:instance_variable_defin
ed?,:remove_instance_variable,:instance_of?,:kind_of?,:is_a?,:tap,:send,:public
_send,:respond_to?,:extend,:display,:method,:public_method,:singleton_method,:d
efine_singleton_method,:object_id,:to_enum,:enum_for,:equal?,:!,:!=,:instance_e
val,:instance_exec,:__send__,:__id__]
Array
81
AynıString'dekigibi,şuArray'inbirröntgeniniçekelim:
Array.class#=>Class
Array.class.superclass#=>Module
Array.class.superclass.superclass#=>Object
Array.class.superclass.superclass.superclass#=>BasicObject
Array.class.superclass.superclass.superclass.superclass#=>nil
Array'inbirüstobjesine?ModuleYineClasskonusundagöreceğizdiyeceğimvesizbanakızacaksınız:)Ruby'debirClassenfazlabaşkabirClass'dantüreyebilir.ÖrneğinPython'dabirClassNTANEClass'taninheritolabilir(Mirasalabilir,türeyebilir)
Ruby,busorunuModuleyapısıylaçözüyor.BumantıklaaslındaortaklaşakullanılanKernelmodülleriyardımıyla,ortakkullanılacakmethod'larbumodüllerinIncludeedilmesiyleilgiliyerleredağıtılıyor.
AcabaArray'dehangimodüllervar?
Array.included_modules#=>[Enumerable,Kernel]
BubakımdanArray,Hashgibinesnelerdebenzerortakmethod'largörmekmümkün.
lengthveyacount
Array'inboyu/içindekaçelemanolduğuileilgilibilgiyialmakiçinkullanılır.
[1,2,3,4].length#=>4
[1,2,3,4].count#=>4
empty?
Arrayacababoşmu?İçindehiçelemanvarmı?
[1,2,3,4].empty?#=>false
[].empty?#=>true
eql?,==,===
Eşitlikkontrolüiçindir.Eğerkarşılığıaynıcinssevebirebiraynıelemanlarasahipsetruedöner.
a=["Uğur","Yeşim","Ezel","Ömer"]
a.eql?(["Yeşim","Ezel","Ömer","Uğur"])#=>false
a.eql?([])#=>false
a.eql?(["Uğur","Yeşim","Ezel","Ömer"])#=>true
Array
82
==GenericEqualityyanigeneleşitlikkontrolüyanihepimizinbildiğikontrol,===iseCaseEqualityyania===bifadesindea,b'ninsubsetimi?demekolur.Örnekverelim:
5.class.superclass#=>Integer
Integer===5#=>true
#5,Integersubsetinde...
Integer.class#=>Class
Integer.class.superclass#=>Module
Integer.class.superclass.superclass#=>Object
Integer.class.superclass.superclass.superclass#=>BasicObject
Integer.class.superclass.superclass.superclass.superclass#=>nil
#Integer,5'insubsetindedeğil.
5===Integer#=>false
include?vemember?
AcabaverdiğimelemanArray'iniçindemi?Verdiğimelemanbudizininüyesimi?
[1,2,3,4].include?(3)#=>true
[1,2,3,4].member?(1)#=>true
[1,2,3,4].member?(5)#=>false
["Uğur","Ezel","Yeşim"].include?("Uğur")#=>true
["Uğur","Ezel","Yeşim"].include?("Ömer")#=>false
array&başka_bir_array
İkidizidedekullanınortakelemanlarıalıryeniArraydöner:
a=[1,2,3,4]
b=[3,1,10,22]
a&b#=>[1,3]
array*int[yada]array*str
a=["a","b","c"]
a*5#=>["a","b","c","a","b","c","a","b","c","a","b","c","a","b","c"]
a*"-vigo-"#=>"a-vigo-b-vigo-c"
*çaparak3elemanlıaArray'indensankibirleştirilmiş15elemanlıyenibirArrayoluşturduk.StringileçarpıncadaaslındajoinmethoduileArray'denStringyaptıkvebirleştiriciolarak-vigo-metnikullandık!
array+başka_array
Array
83
İkiArray'itoplarveyeniArraydöner:
a=["Uğur","Yeşim","Ezel"]
b=["Ömer"]
a+b#=>["Uğur","Yeşim","Ezel","Ömer"]
array-başka_array
Array'lerarasındakifarkıArrayolarakbulmak:
a=["Uğur","Yeşim","Ezel"]
b=["Uğur","Yeşim"]
a-b#=>["Ezel"]#a'daolabbelemanlarıkayboldu
array|başka_array
İkiArray'iunique(tekil)elemanlarolarakbirleştirdi.Aynıelemanvarsabunlardanbirinialdı:
a=["Uğur","Yeşim","Ezel"]
b=["Uğur","Ömer"]
a|b#=>["Uğur","Yeşim","Ezel","Ömer"]
array<<nesneyadapush
Array'insonunaelemaneklemekiçinkullanılır.
a=["Uğur","Yeşim","Ezel"]
a<<"Ömer"#=>["Uğur","Yeşim","Ezel","Ömer"]
a.push("Eren")#=>["Uğur","Yeşim","Ezel","Ömer","Eren"]
Kezazincirlemeçağrıdayapabilirsiniz:
a.push("Tunç").push("Suat")#=>["Uğur","Yeşim","Ezel","Ömer","Eren","Tunç","S
uat"]
concat
ArraysonunaArrayeklemekiçinkullanılır.
a=[1,2,3]
a.concat([4,5,6])
a#=>[1,2,3,4,5,6]
join
Array
84
ArrayelemanlarınıbirleştiripString'eçevirmeyeyarar.Eğerparametreverirsekaradakibirleştiriciyidebelirlemişoluruz.
["Commodore64","Amiga","Sinclair","Amstrad"].join#=>"Commodore64AmigaSi
nclairAmstrad"
["Commodore64","Amiga","Sinclair","Amstrad"].join(",")#=>"Commodore64,Amig
a,Sinclair,Amstrad"
unshift
Array'inbaşınaelemaneklemekiçinkullanılır.
a=["Uğur","Yeşim","Ezel"]
a.unshift("Ömer")#=>["Ömer","Uğur","Yeşim","Ezel"]
insert
Array'deistediğinizbirnoktayaelemaneklemekiçinkullanılır.İlkparametreindexdiğerparametre/lerdeeklenecekeleman/lar.
a=["Uğur","Yeşim","Ezel"]
a.insert(1,"Ömer")#=>["Uğur","Ömer","Yeşim","Ezel"]
a.insert(1,"Ahmet","Ece","Eren")#=>["Uğur","Ahmet","Ece","Eren","Ömer","Yeş
im","Ezel"]
replace
Array'iniçini,diğerArray'ledeğiştirir.AslındaArray'ibaşkabirArray'eeşitlemekgibidir.Elemansayısınıneşitolupolmamasıhiçönemlideğildir.
a=["Uğur","Yeşim","Ezel","Ömer"]
a.replace(["Foo","Bar"])#=>["Foo","Bar"]
a#=>["Foo","Bar"]
array<=>başka_array
Spaceshipoperatöründenbahsetmiştik.Array'lerarasındakarşılaştırmayapmayısağlar.
[1,2,3,4]<=>[1,2,3,4]#=>0#Eşit
[1,2,3,4]<=>[1,2,3]#=>1#İlkdeğerbüyük
[1,2,3]<=>[1,2,3,4]#=>-1#İlkdeğerküçük
pop,shift,delete,delete_at,delete_if
Sonelemanıçıkartmankiçinpopilkelemanıçıkartmakiçinshiftkullanılır.Herhangibirelemanıçıkartmakiçindelete,belirlibirindex'dekielemanıçıkartmakiçindelete_atkullanılır.
Array
85
a=["Uğur","Ömer","Yeşim","Ezel","Eren"]
a.pop#=>"Eren"
a#=>["Uğur","Ömer","Yeşim","Ezel"]
a.shift#=>"Uğur"
a#=>["Ömer","Yeşim","Ezel"]
a.delete("Ömer")#=>"Ömer"
a#=>["Yeşim","Ezel"]
a.delete_at(1)#=>"Ezel"
a#=>["Yeşim"]
#not50'denküçüksesil:)
notlar=[40,45,53,70,99,65]
notlar.delete_if{|notu|notu<50}#=>[53,70,99,65]
pop'aparametregeçerseksonntaneyiuçurmuşoluruz:
a=["Uğur","Ömer","Yeşim","Ezel","Eren"]
a.pop(2)#=>["Ezel","Eren"]
a#=>["Uğur","Ömer","Yeşim"]
compactveuniq
nilelemanlarıuçurmakiçincompact,duplikeelemanlarıtekilhalegetirmekiçinuniqkullanılır.
["a",1,nil,2,nil,"b",1,"a"].compact#=>["a",1,2,"b",1,"a"]
["a",1,nil,2,nil,"b",1,"a"].uniq#=>["a",1,nil,2,"b"]
["a",1,nil,2,nil,"b",1,"a"].compact.uniq#=>["a",1,2,"b"]
array==başka_array
İkiArraynitelikvenicelikolarakbirbirineeşitmi?
[1,2,3,4]==[1,2,3,4]#=>true
[1,2,3,4]==["1",2,3,4]#=>false
[1,2,3,4]==[1,2,3]#=>false
assocverassoc
ElemanlarıArrayolanbirArrayiçinde,ilkdeğeregöreyakalamayapmayayarar.
Array
86
a=["renkler","kırmızı","sarı","mavi"]
b=["harfler","a","b","c"]
c="foo"
t=[a,b,c]
t#=>[["renkler","kırmızı","sarı","mavi"],["harfler","a","b",
"c"],"foo"]
t.assoc("renkler")#=>["renkler","kırmızı","sarı","mavi"]
t.assoc("foo")#=>nil
t.rassoc("kırmızı")#=>["renkler","kırmızı","sarı","mavi"]
rassociseikincielemanınabakar,yani"renkler"yerine"kırımızı"kullanabiliriz:
slice(başlangıç,boy)yadaslice(aralık)
ArrayiçindenkesipbaşkabirArrayoluşturmakiçinkullanılır.başlangiçindeks'indekielemandahilolmaküzere,boyyadaaralıkkadarınıkes.
[1,2,3,4].slice(0,2)#=>[1,2]#0.danitibaren2tane
[1,2,3,4].slice(2..4)#=>[3,4]#2.denitibaren2tane
firstvelast
Adındandaanlaşılacağıgibi,Array'inilkvesonelemanlarıiçinkullanılır:
a=[1,2,3,4,5]
a.first#=>1
a.last#=>5
Eğerparametregeçersek,ilknyadasonnelemanlarıalabiliriz:
a=[1,2,3,4,5]
a.first(2)#=>[1,2]
a.last(2)#=>[4,5]
find(detect),find_all,index,find_index
findileblokiçindekoşulauyanilkArrayelemanını,find_alliletümünüalırız:
["Uğur","Yeşim","Ezel","Ömer"].find{|n|n.length>3}#=>"Uğur"
["Uğur","Yeşim","Ezel","Ömer"].find_all{|n|n.length>3}#=>["Uğur","Yeşim",
"Ezel","Ömer"]
detectilefindaynıişiyapar.
index,find_indexileelemanınindex'inibuluruz:
Array
87
["a","b","c","d","e"].index("e")#=>4
["Uğur","Yeşim","Ezel","Ömer"].index("Ezel")#=>2
["Uğur","Yeşim","Ezel","Ömer"].find_index("Ezel")#=>2
clear
Array'itemizlemekiçinkullanılır:)
a=[1,2,3]
a.clear#=>[]
a#=>[]
reverse
Array'iterseçevir.
a=[1,2,3,4,5]
a.reverse#=>[5,4,3,2,1]
sample
Array'denrandomolarakelemanalmayayarar.Eğerparametregeçilirsegeçilenadetkadarrandomelemandöner.
a=[1,2,3,4,5]
a.sample#=>3
a.sample(3)#=>[5,1,3]
shuffle
Array'iniçindekielemanlarınindex'lerinikarıştırı:)
a=[1,2,3,4,5]
a.shuffle#=>[5,4,1,3,2]
a.shuffle#=>[1,2,3,5,4]
sort
Arrayiçindekielemanları<=>mantığıylasıralar.
a=[1,4,2,3,11,5]
a.sort#=>[1,2,3,4,5,11]
b=["a","c","b","z","d"]
b.sort#=>["a","b","c","d","z"]
fill
Array
88
Array'iniçiniilgilideğerledoldurmakiçinkullanılır.İşlemsonucundaorijinalArray'indeğerideğişir.YanineilefillettiysenizArrayartıkodeğerlerdedir.
a=["Uğur","Yeşim","Ezel","Ömer"]
a.fill("x")#=>["x","x","x","x"]#tümelemanlarıxyaptı
a#=>["x","x","x","x"]#artıka'nınyenideğeribu
a=["Uğur","Yeşim","Ezel","Ömer"]
a.fill("y",2)#=>["Uğur","Yeşim","y","y"]#2.denitibarenyiledoldur
a=["Uğur","Yeşim","Ezel","Ömer"]#2.denitibaren1tanedoldur
a.fill("z",2,1)#=>["Uğur","Yeşim","z","Ömer"]
Keza;
a=[1,2,3,4,5]
a.fill{|i|i*5}#=>[0,5,10,15,20]
a#=>[0,5,10,15,20]
şeklindedekullanılır.
flatten
ArrayiçindeArrayelemanlarıvarsa,tekharekettebunlarıdüztekbirArrayhalinegetirebiliriz.
[1,2,["a","b",:c],[66,[5.5,3.1]]].flatten#=>[1,2,"a","b",:c,66,5.5,3.
1]
rotate
Arrayelemanlarıkendiiçindekaydırır.
a=[1,2,3,4,5]
a.rotate#=>[2,3,4,5,1]#1kaydırdı
a.rotate(2)#=>[3,4,5,1,2]#2kaydırdı,ilk2elemanısonakoydu!
Varsayılandeğer1'dir.
zip
a=[4,5,6]
b=[7,8,9]
[1,2,3].zip(a,b)#=>[[1,4,7],[2,5,8],[3,6,9]]
[1,2].zip(a,b)#=>[[1,4,7],[2,5,8]]
a.zip([1,2],[8])#=>[[4,1,8],[5,2,nil],[6,nil,nil]]
Array
89
[1,2,3].zip(a,b)işleminiyaparken,önce0.elemanıyani1'ialdı,sonraa'nun0.elemanınıaldı,sonradab'nin0.elemanınıaldıvepaketledi:[1,4,7]aynıişi1.ve2.elemanlariçinyaptı.
[1,2].zip(a,b)yaparken,Arrayboylarıeşitolmadığıiçin[1,2]sadece2elemanlıolduğuiçinbuişlemi0.ve1.elemanlariçinyaptı.
Sonörnekteindex'ekarşılıkgelmediğiiçinelemanlarnilgeldi!
transpose
ArrayiçindekiArray'lerisatırgibidüşünüpbunlarısütunaçeviriyorgibialgılayabilirsiniz.
a=[[1,2],[3,4],[5,6]]
a.transpose#=>[[1,3,5],[2,4,6]]
#[
#[1,2],
#[3,4],
#[5,6]
#]
#->[1,3,5],[2,4,5]
#
TipÇeviricilerito_aveto_arykendisinidöner,asılgörevieğeraltsınıftançağrılmışsa,yaniArray'dentüreyenbaşkabirClass'dakullanıldığındadirekArray'edönüştürür.
["a",1,"b",2].to_a#=>["a",1,"b",2]
["a",1,"b",2].to_ary#=>["a",1,"b",2]
[["a",1],["b",2]].to_h#=>{"a"=>1,"b"=>2}
["a",1,"b",2].to_s#=>"[\"a\",1,\"b\",2]"
["a",1,"b",2].inspect#=>"[\"a\",1,\"b\",2]"
entriesdeaynento_agibiçalışır:
(1..3)#=>1..3
(1..3).entries#=>[1,2,3]
(1..3).to_a#=>[1,2,3]
grep
AslındabukonularıRegularExpressions'dagöreceğizamayerigelmişkenhızladeğinelim.ArrayiçindeelemanlarıRegexkoşullarınagörefiltreleyebiliyoruz:
Array
90
(1..10).to_a#=>[1,2,3,4,5,6,7,8,9,10]
#2'den5'ekadar(5dahil)
(1..10).grep2..5#=>[2,3,4,5]
#sadece.comolanelemanlarıal
["a","http://example.com","b","foo","http://webbox.io"].grep(/^http.+\.com/)#=>
["http://example.com"]
pack
Array'iniçeriğiniverilendirektifegöreBinaryStringhalinegetirir.Uzuncabirdirektiflistesivar.
#A:Stringolarakişle,spacekarakterikullan
#5:Uzunluğu5karakterolsun
["a","b","c"].pack("A5A5A5")#=>"abc"
#Uzunluğu5'tenbüyükolankesintiyeuğradı
["ali","burak","cengiz"].pack("A5A5A5")#=>"aliburakcengi"
#a:Stringolarakişle,nullyani\x00karakterikullan
["a","b","c"].pack("a3a3a3")#=>"a\x00\x00b\x00\x00c\x00\x00"
İterasyonveBlockKullanımıcollect/map{|eleman|blok}→yeni_array
Blokiçindegelenkoduherelemanauygular,yeniArraydöner:
a=[1,2,3,4,5]
a.collect{|i|i*2}#=>[2,4,6,8,10]
a.collect{|i|"sayı#{i}"}#=>["sayı1","sayı2","sayı3","sayı4","sayı5"]
mapdeaynıişiyapar:
["Uğur","Yeşim","Ezel","Ömer"].map{|isim|"İsim:#{isim}"}#=>["İsim:Uğur","
İsim:Yeşim","İsim:Ezel","İsim:Ömer"]
["Uğur","Yeşim","Ezel","Ömer"].collect{|isim|"İsim:#{isim}"}#=>["İsim:Uğur
","İsim:Yeşim","İsim:Ezel","İsim:Ömer"]
select
Blokiçindengelenifadenintrue/falseolmasınagörefiltreyaparveyeniArraydöner:
Array
91
[1,2,3,10,15,20].select{|n|n%2==0}#=>[2,10,20]#2'yetambölünenler
[1,2,"3","ali",15,20].select{|n|n.is_a?(Fixnum)}#=>[1,2,15,20]#sadece
sayılar
reject
selectintersidir.
[1,2,3,10,15,20].reject{|n|n%2==0}#=>[1,3,15]#2'yetambölülenleri
at
[1,2,"3","ali",15,20].reject{|n|n.is_a?(Fixnum)}#=>["3","ali"]#Sayıola
nlarıat
keep_if
Blokiçindekiifade'densadecefalsedönenleriatarveArray'inorjinaldeğerinibozar,değiştirir.
a=[1,2,3,10,15,20]
a.keep_if{|n|n%2==0}#=>[2,10,20]#2'yebölünemeyenlerfalsegeldiğiiçin
düştüler.
a#=>[2,10,20]#aartıkbu!
combination(n){|c|blok}→array
Matematiktekikombinasyonişlemidir.1,2ve3sayılarının2'likombinasyonu:
a=[1,2,3]
a.combination(1).to_a#=>[[1],[2],[3]]
a.combination(2).to_a#=>[[1,2],[1,3],[2,3]]
a.combination(2){|c|puts"Olasıklar:#{c.join("ve")}"}
#Olasıklar:1ve2
#Olasıklar:1ve3
#Olasıklar:2ve3
permutation
Aynıkombinasyongibi,matematiktekipermutasyonişlemidir.
[1,2,3].permutation.to_a#=>[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2]
,[3,2,1]]
Eğerparametregeçersekkaçlıpermutasyonolduğunubelirtiriz:
Array
92
[1,2,3].permutation(1).to_a#=>[[1],[2],[3]]
[1,2,3].permutation(2).to_a#=>[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
repeated_combination,repeated_permutation
combinationilerepeated_combinationarasındakifarkıörneklegörelim:
[1,2,3].combination(1).to_a#=>[[1],[2],[3]]
[1,2,3].repeated_combination(1).to_a#=>[[1],[2],[3]]
[1,2,3].combination(2).to_a#=>[[1,2],[1,3],[2,3]]
[1,2,3].repeated_combination(2).to_a#=>[[1,1],[1,2],[1,3],[2,2],[2,3],[
3,3]]
combinationolasıtekilsonucu,repeated_combinationpasedilensayıyagöretekrardaedebilensonucudöner.Aynısırepeated_permutationiçindegeçerlidir:
[1,2,3].permutation(1).to_a#=>[[1],[2],[3]]
[1,2,3].repeated_permutation(1).to_a#=>[[1],[2],[3]]
[1,2,3].permutation(2).to_a#=>[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
[1,2,3].repeated_permutation(2).to_a#=>[[1,1],[1,2],[1,3],[2,1],[2,2],[
2,3],[3,1],[3,2],[3,3]]
product
ArrayveargümanolarakgeçilecekdiğerArray/lerinelemanlarıylaoluşabilecektümalternatifleriüretmenizisağlar.
[1,2,3].product#=>[[1],[2],[3]]
[1,2,3].product([4,5])#=>[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
[1,2,3].product([7,8,9])#=>[[1,7],[1,8],[1,9],[2,7],[2,8],[2,9],[3,
7],[3,8],[3,9]]
[1,2,3].product(["a","b"],["x","y"])#=>[[1,"a","x"],[1,"a","y"],[1,"b",
"x"],[1,"b","y"],[2,"a","x"],[2,"a","y"],[2,"b","x"],[2,"b","y"],[3,
"a","x"],[3,"a","y"],[3,"b","x"],[3,"b","y"]]
count
Azöncemethodolarakişlediğimizcountilebaşkailginçişlerdeyapabiliyoruz:
a=[1,2,3,4,2]
a.count#=>5#elemansayısı
a.count(2)#=>2#kaçtane2var?
a.count{|n|n%2==0}#=>3#kaçtane2'yetambölünenvar?
cycle(n=nil){|obje|blok}→nil
Array
93
Pasedilenblok'undefatekrareder.
a=[1,2,3]
a.cycle(2).to_a#=>[1,2,3,1,2,3]#2defa
a.cycle(4).to_a#=>[1,2,3,1,2,3,1,2,3,1,2,3]#3defa
a.cycle(2){|o|puts"Sayı#{o}"}
#Sayı1
#Sayı2
#Sayı3
#Sayı1
#Sayı2
#Sayı3
Eğer[1,2,3].cycle{|i|putsi}gibibirişlemyaparsanız,defaultolaraknilgeçmişolursunvebusonsuzdöngülegirer,sonsuzakadar1,2,3,1,2,3....şeklindedevameder!
drop_while{|array|blok}→yeniarray
delete_ifileaynıişiyapar.
notlar=[40,45,53,70,99,65]
notlar.drop_while{|notu|notu<50}#=>[53,70,99,65]
KoşulagöreArray'denatargibidüşünebilirsiniz.Not50'denküçüksebırak.
take_while
Aynıdrop_whilegibiçalışıramatersiniyapar:
notlar=[40,45,53,70,99,65]
notlar.take_while{|notu|notu<50}#=>[40,45]
KoşulagöreArray'eeklergibidüşünebilirsiniz.Not50'denküçüksesepeteekle!:)
each,each_index,each_with_index,each_slice,each_cons,each_with_object,reverse_each
ArrayvehattaEnumator'lerincandamarıdır.Rubyyazarkensizdegöreceksinizeachensıkkullandığınıziterasyon(yineleme/tekrarlama)yöntemiolacak.
Array
94
a=["Uğur","Yeşim","Ezel","Ömer"]
a.each#=>#<Enumerator:["Uğur","Yeşim","Ezel","Ömer"]:each>
a.each{|isim|puts"İsim:#{isim}"}
#İsim:Uğur
#İsim:Yeşim
#İsim:Ezel
#İsim:Ömer
Arrayveiçindedolaşılabilirhernesnedeişeyarar.Birdebununindex'lihalivar;
a=["Uğur","Yeşim","Ezel","Ömer"]
a.each_index#=>#<Enumerator:["Uğur","Yeşim","Ezel","Ömer"]:each_index>
a.each_index.to_a#=>[0,1,2,3]
a.each_index{|i|puts"Index:#{i},Değeri:#{a[i]}"}
#Index:0,Değeri:Uğur
#Index:1,Değeri:Yeşim
#Index:2,Değeri:Ezel
#Index:3,Değeri:Ömer
yadabuişi;
a=["Uğur","Yeşim","Ezel","Ömer"]
a.each_with_index{|eleman,index|puts"index:#{index},eleman:#{eleman}"}
#index:0,eleman:Uğur
#index:1,eleman:Yeşim
#index:2,eleman:Ezel
#index:3,eleman:Ömer
each_slicedaArray'igruplamak,parçalaraayırmakiçindir.Geçilenparametrebuişeyarar:
a=["Uğur","Yeşim","Ezel","Ömer"]
a.each_slice(2)#=>#<Enumerator:["Uğur","Yeşim","Ezel","Ömer"]:each_slice(2)>
a.each_slice(2).to_a#=>[["Uğur","Yeşim"],["Ezel","Ömer"]]
a.each_slice(2){|ikili_grup|puts"#{ikili_grup}"}
#["Uğur","Yeşim"]
#["Ezel","Ömer"]
each_consiseslicegibiamamutlakabelirtilenmiktardaparçaüretir.
Array
95
#3'lüüret
[1,2,3,4,5,6].each_cons(3).to_a#=>[[1,2,3],[2,3,4],[3,4,5],[4,5,6]]
#4'lüüret
[1,2,3,4,5,6].each_cons(4).to_a#=>[[1,2,3,4],[2,3,4,5],[3,4,5,6]]
each_with_objectdeise,iterasyonagirerkenbirnesnepasedip,onesneyidoldurabilirsiniz.
[1,2,3,4].each_with_object([]){|number,given_object|
given_object<<number*2
}#=>[2,4,6,8]
numberArray'dengeleneleman(1,2,3,4gibi),given_objectiseeach_with_object([])method'dageçtiğimizboşArray[].
reverse_eachaslındaArray'iotomatikolaraktersçeviriryanireverseederveiçindedolaşmanızısağlar:
computers=["Commodore64","Amiga","Sinclair","Amstrad"]
computers.reverse_each#=>#<Enumerator:["Commodore64","Amiga","Sinclair","Amstr
ad"]:reverse_each>
computers.reverse_each.to_a#=>["Amstrad","Sinclair","Amiga","Commodore64"]
computers.reverse_each{|c|puts"Bilgisayar:#{c}"}
#Bilgisayar:Amstrad
#Bilgisayar:Sinclair
#Bilgisayar:Amiga
#Bilgisayar:Commodore64
find_index
İndeks'iararkenblokişleyebiliriz:
computers=["Commodore64","Amiga","Sinclair","Amstrad"]
computers.find_index{|c|c=="Amstrad"}#=>3
freezevefrozen?
Array'ikitlemekiçinkullanılır.Yanifreeze(dondurulmuş)birArray'eyenielemaneklenemez.KezaArray#sortesnasındadaotomatikolarakfreezeolursortbitincebuzçözülür!
a=["Uğur","Yeşim","Ezel","Ömer"]
a.freeze
a<<"Fazilet"#Yeniisimeklemekmümkündeğildir!
Array
96
RuntimeError:can'tmodifyfrozenArray
Array'debuzlanmavarmıyokmuanlamakiçinfrozen?kullanırız:
a=["Uğur","Yeşim","Ezel","Ömer"]
a.freeze#=>["Uğur","Yeşim","Ezel","Ömer"]
a.frozen?#=>true
min,max,minmax,min_by,max_byveminmax_by
minvemaxileArrayelemanlarındanenküçük/büyükdeğerialırız:
a=[6,1,8,4,11]
a.min#=>1
a.max#=>11
Pekisayıyerinemetinlerolsaneolacaktı?
m=["a","ab","abc","abcd"]
m.min#=>"a"
m.max#=>"abcd"
peki,mArray'işöyleolsaydı:m=["a","ab","abc","abcd","111111111"]sonuçneolurdu?
m=["a","ab","abc","abcd","111111111"]
m.min#=>"111111111"#?
m.max#=>"abcd"
ÖnceComparablemıdiyerbakılır,sayılariçinçalışanbuyöntem,Stringdea<=>bkarşılaştırmasınagirerveLexicologicalkarşılaştırmayapar."111111111"karaktersayısıolarakdiğerlerinegöreçokolmasınarağmen,mindeğerolarakgelir.Eğerkaraktersayınagörekarşılaştırmayapmakgerekiyorsa;
m=["a","ab","abc","abcd","111111111"]
m.min{|a,b|a.length<=>b.length}#=>"a"
m.max#=>"abcd"
Şeklindeyapmakgerekir.Blokkullanabildiğimiziçinaynıişmaxiçindegeçerlidir.Yadabuişleriyapabilmekiçinmin_byvemax_bykullanabiliriz:
Array
97
m=["a","ab","abc","abcd","111111111"]
m.min_by{|x|x.length}#=>"a"
m.max_by{|x|x.length}#=>"111111111"
minmaxdaArray'inminimumvemaximum'unudöner:
m=["a","ab","abc","abcd"]
m.min#=>"a"
m.max#=>"abcd"
m.minmax#=>["a","abcd"]
Aynımantıktaminmax_bydagereklişartagöremin,maxdöner:
m=["a","ab","abc","abcd"]
m.minmax_by{|x|x.length}#=>["a","abcd"]
all?,any?,one?,none?
Arrayiçindekielemanlarıbellibirkoşulagörekontroletmekiçinkullanılır.SonuçBooleanyanitrueyadafalsedöner.Tümelemanlarınkontrolükoşulauyuyorsatrueuymuyorsafalsedöner.
#acabahayvanlardizisindekiisimlerinhepsininuzunluğu
#enaz2karaktermi?
hayvanlar=["Kedi","Köpek","Kuş","Kurbağa","Kaplumbağa"]
hayvanlar.all?{|hayvan_ismi|hayvan_ismi.length>=2}#=>true
#AcabailkkarfleriKharfimi?
hayvanlar.all?{|hayvan_ismi|hayvan_ismi.start_with?("K")}#=>true
#Elemanlarınherbiritruemu?
[true,false,nil].all?#=>false
any?deyanlızcabirtanesitrueolsayeterlidir:
#EnazındanbirhayvanismiAilebaşlıyormu?
hayvanlar=["Kedi","Köpek","At","Yılan","Balık"]
hayvanlar.any?{|hayvan_ismi|hayvan_ismi.start_with?("A")}#=>true
one?daisesadecebirelemankoşulauymalıdır.Yanibirtanesitruedönmelidir.Eğerbirdenfazlaelemankoşulatruedönersesonuçfalseolur:
Array
98
hayvanlar=["Kedi","Köpek","At","Yılan","Balık","Kaplumbağa"]
#Sadecebirisminuzunluğu6karatertenbüyükolmalı!
hayvanlar.one?{|hayvan_ismi|hayvan_ismi.length>6}#=>true
#Uzunluğu3'tenbüyük5isimolduğuiçinfalsedöndü!
hayvanlar.one?{|hayvan_ismi|hayvan_ismi.length>3}#=>false
none?daisehepsifalseolmalıdırkisonuçtruedönsün:
hayvanlar=["Kedi","Köpek","At","Yılan","Balık","Kaplumbağa"]
#Hiçbirisminuzunluğu2karakterolmamalı?false.At'ınuzunluğu2
hayvanlar.none?{|hayvan_ismi|hayvan_ismi.length==2}#=>false
#Cilebaşlayanhayvanismiolmasın!true.HiçbirisimCilebaşlamıyor
hayvanlar.none?{|hayvan_ismi|hayvan_ismi.start_with?("C")}#=>true
inject,reduce*
injectvereduceaynıişiyaparlarvebirtürakümülatorişlemiyapmayayararlar.Blokiçinde2paramtrekullanılır.Başlamaparametresidealabilir.ÖrneğinArray[1,2,3,4,5]vetümelemanlarıbirbiriyletoplamakisitiyoruz.
[1,2,3,4,5].inject{|toplam,eleman|toplam+eleman}#=>15
#işlemşuşekildeilerliyor
#toplam:0,eleman:1
#toplam:1,eleman:2
#toplam:3,eleman:3
#toplam:6,eleman:4
#toplam:10,eleman:5
#sonageldiğindetoplam10,eleman5->10+5=15
Eğerbaşlangıçdeğeriiçinparametregeçseydik,örneğin10:
[1,2,3,4,5].inject(10){|toplam,eleman|toplam+eleman}#=>25
#toplam:10,eleman:1
#toplam:11,eleman:2
#toplam:13,eleman:3
#toplam:16,eleman:4
#toplam:20,eleman:5
#sonageldiğindetoplam20,eleman5->20+5=25
Aynıişireduceiledeyapabilirdik.
[1,2,3,4,5].reduce(:+)#=>15
Array
99
Örnekteherelemanın+methodu'nuçağırıyoruzvesankix=x+1mantığında,kendisiniekleyeekleyesonucavarıyoruz.
en_uzun_hayvan_ismi=["kedi","köpek","kamplumbağa"].injectdo|buffer,hayvan|
buffer.length>hayvan.length?buffer:hayvan
end
en_uzun_hayvan_ismi#=>"kamplumbağa"
partitionvegroup_by
partitionArray'i2parçayaayırmayayarar.Sonuç,blok'taişlenenifadeyebağlıolarak[true_array,false_array]olarakdöner.Yanikoşulatruecevapverenlerlefalsecevapverenlerayrıparçalarhalindedöner:)
[1,2,3,4,5,6].partition{|n|n.even?}#=>[[2,4,6],[1,3,5]]
#Çiftsayılar,true_arrayyaniilkparça:[2,4,6]
#Teksayılar,false_arrayyaniikinciparça:[1,3,5]
#Sadeceçiftsayılargelsin:
[1,2,3,4,5,6].partition{|n|n.even?}[0]#=>[2,4,6]
group_bygruplamayapmakiçinkullanılır.SonuçHashdöner,ilkdeğer(key)blokiçindekiifadeninsonucu,ikincideğer(value)isesonucuverenlerinoluşturdugruptur.1'den6'yakadarsayıları3'ebölüncekaçkaldığınıgruplayarakbulalım:
[1,2,3,4,5,6].group_by{|n|n%3}#=>{1=>[1,4],2=>[2,5],0=>[3,6]}
#3'ebölüncekalanı;
#1olanlar:[1,4]
#2olanlar:[2,5]
#0olanlar(tambölünenler):[3,6]
Notu50'denbüyükolanlar:
notlar=[50,20,44,60,80,100,99,81,5]
notlar.group_by{|notu|notu>40}[true]#=>[50,44,60,80,100,99,81]
chunk
Arrayelemanlarıkoşulagöregruplar.
Array
100
[3,1,4,1,5,9,2,6,5,3,5].chunk{|n|n.even?}.to_a
#=>[
#[false,[3,1]],
#[true,[4]],
#[false,[1,5,9]],
#[true,[2,6]],
#[false,[5,3,5]]
#]
slice_before
Arrayiçindebellibirelemanayadakuralagöreparçalaraayırmakiçinkullanılır.
[1,2,3,'a',4,5,6,'a',7,8,9,'a',1,3,5].slice_before{|i|i=='a'
}.to_a
#=>[[1,2,3],["a",4,5,6],["a",7,8,9],["a",1,3,5]]
flat_map,collect_concat
İkisideaynıişiyapar.
Öncemapedersonraflattenyapar.
pos_neg=[1,2,3,4,5,6].map{|n|[n,-n]}
pos_neg#=>[[1,-1],[2,-2],[3,-3],[4,-4],[5,-5],[6,-6]]
pos_neg.flatten#=>[1,-1,2,-2,3,-3,4,-4,5,-5,6,-6]
#yerine:
[1,2,3,4,5,6].flat_map{|n|[n,-n]}#=>[1,-1,2,-2,3,-3,4,-4,5,-5,6
,-6]
sort_by
Aynısortgibiçalışır,Blokkullanır.İfadenintrueolmasınagöreçalışır:
hayvanlar=["kamplumbağa","at","eşşek","kurbağa","ayı"]
#isimleriuzunluklarınagöreküçüktenbüyüğedoğrusıralayalım
hayvanlar.sort_by{|isim|isim.length}#=>["at","ayı","eşşek","kurbağa","kamplu
mbağa"]
#isimleriuzunluklarınagörebüyüktenküçüğedoğrusıralayalım
hayvanlar.sort_by{|isim|-isim.length}#=>["at","ayı","eşşek","kurbağa","kampl
umbağa"]
bsearch
Binaryaramayapar,O(logn)formülünüuygular,buradakinArray'inboyudur.Findminimumgibidir,yanikoşulailkuyanıbulgibi...
Array
101
#2'denbüyük3,4ve5olmasınarağmenteksonuç
[1,2,3,4,5].bsearch{|n|n>2}#=>3
[1,2,3,4,5].bsearch{|n|n>=4}#=>4
TehlikeliİşlemlerBaşlardadabahsettiğimizgibimethodismi!ilebitiyorsabuilgilinesnededeğişiklikyapıyorolduğumuzanlamınagelir.Array'lerdedebutürmethod'larvar:
[:reverse!,:rotate!,:sort!,:sort_by!,:collect!,:map!,:select!,:reject!,:slice!
,:uniq!,:compact!,:flatten!,:shuffle!]
Bumethod'larorijinalArray'ibozar.Yani;
a=[1,2,3,4,5]
a.reverse!#=>[5,4,3,2,1]
#aartıkreverseedilmişhalde!
a#=>[5,4,3,2,1]
Array
102
HashPekçokdildeDictionaryolarakgeçen,Array'imsi,hattaAssociativeArraydedenir,Key-ValueçiftibarındıranyineArray'ebenzeyenbaşkabirtaşıyıcıdır.Key-Valuedediğimizşeyise;
{key1:"value1",key2:"value2",....}
şeklindedir.Yukarıdakiörnek,yenisyntax'ıkullanır.Rubyprogramcılarınınalışıkolduğuörnek:
{"key1"=>"value1","key2"=>"value2",...}
yada
{:key1=>"value1",:key2=>"value2",...}
şeklindedir.Hepsiaynıkapıyaçıkar...Array'dekisıra(index)mantığıburadakey'lerileoluyorgibidüşünebilirsiniz.Key'lerunique'diryanibirHashiçinde2taneaynıkey'denolamaz.
Hash'desonuçtabirclassolduğuiçinnewmethod'uileHash'ioluşturabiliriz;
Hash.new#=>{}
AynıArray'dekigibiHash'indehızlıoluşurmayoluvar:h={}.HemenHash'inneredengeldiğinebakalım:
Hash.class#=>Class
Hash.class.superclass#=>Module
Hash.class.superclass.superclass#=>Object
Hash.class.superclass.superclass.superclass#=>BasicObject
Hash.class.superclass.superclass.superclass.superclass#=>nil
DikkatettiysenizHash'inbirüstsınıfıModule.AynıArray'dekigibi.Pekibumodüllernelermiş?
Hash.included_modules#=>[Enumerable,Kernel]
EğerHash'ioluştururkendefaultdeğergeçersek,tanımsızolankeyiçindeğeratamışoluruz:
Hash
103
h=Hash.new("Tanımsız")#=>{}
h[:isim]="Uğur"#=>"Uğur"
h#=>{:isim=>"Uğur"}
h[:soyad]#=>"Tanımsız"
h.default#=>"Tanımsız"
Olmayanbirkey'eulaşmakistediğimizde"Tanımsız"değerigeldi.Eğerbudefaultdeğeriatamasaydıneolacaktı?
h=Hash.new#=>{}
h[:isim]="Uğur"#=>"Uğur"
h[:soyad]#=>nil
nilgelecekti.Birazsonragöreceğimizfetchmethod'unulütfenaklınızdatutun!
Defaultdeğertanımlamamantığında;
h=Hash.new{|hash,key|hash[key]="User:#{key}"}
h["vigo"]#=>"User:vigo"
h["foobar"]#=>"User:foobar"
h["animal"]="horse"#=>"horse"
h#=>{"vigo"=>"User:vigo","foobar"=>"User:foobar","animal"=>
"horse"}
butarzilginçbiryöntemdekullanılabilir.Normaldevigokey'inekarşılıkvalueyokamaHashinnewmethod'undayaptığımızbirblokişlemiileolmayankeyiçindeğeratamasıyaptığımızgibikey-valueatamasıdayapabiliyoruz.
HashClassMethod'larıHash'denbirinstanceoluşturmadankullandığımızmethodlardır.
Hash[key,value,...]->yeni_hashHash[[[key,value],...]]->yeni_hashHash[object]->yeni_hash
Hash["user_count",5]#=>{"user_count"=>5}
Hash[[["user_count",5],["active_users",2]]]#=>{"user_count"=>5,"active_users"
=>2}
Hash["user_count"=>5,"active_users"=>2]#=>{"user_count"=>5,"active_users"
=>2}
Hash.new
Zatenilgiliörnekleribaştavermiştik,tekraredelim:
Hash
104
h=Hash.new
h#=>{}
h["user_count"]=5
h#=>{"user_count"=>5}
h=Hash.new{|hash,key|hash[key]="UserID:#{key}"}
h["1"]#=>"UserID:1"
h["2"]#=>"UserID:2"
h#=>{"1"=>"UserID:1","2"=>"UserID:2"}
try_convert(obj)→hashyadanil
Hash'edönüşebilmeihtimaliolannesneyiHashhalineçevirir.
Hash.try_convert({"user_count"=>5})#=>{"user_count"=>5}
Hash.try_convert("user_count=>5")#=>nil
HashInstanceMethod'larıHashinstance'ıoluşturduktansonrakullanacağımızmethod'lardır.
Önceklasikdeğerokumavedeğeratamaişlerinebakalım.Zatenbunoktayakadarkabacabiliyoruznasıldeğeratarızgeriokuruz.Amabirazkafalarıkarıştırmakistiyorum:
h={username:"vigo",password:"1234"}#=>{:username=>"vigo",:password=>"1234"}
YukarıdakigibibirHash'imizvar.Dikkatettiyseniz,key,valueolarakbaktığımızda:usernameve:passworddiyebaşlayankeylervar...Hatta:
h.keys#=>[:username,:password]
diyedesağlamasınıyaparız.Peki,yenibirkeytanımlasak?h["useremail"]="[email protected]".Tekrarbakalımkeylere:
h.keys#=>[:username,:password,"useremail"]
BirsonrakibölümdekarşımızaçıkacakolanSymboltipiilekarşıkarşıyayız.Sadecesymbolmu?hayır,karışıkkeylervarelimizde.Hemensağlamasınıyapalım:
h.keys.map(&:class)#=>[Symbol,Symbol,String]
Hash
105
İlkikikeySymbolikensonkeyStringoldu.DemekkiHashiçinekeycinsiolarakkarşıkatamayapabiliniyor.Birazsıkıntılıbirdurumamagenelkültürmahiyetindeaklınızdatutunbunu!
ŞimdigenelolarakHashhangimethod'larasahiphemenbakalım:
h=Hash.new
h.methods#=>[:rehash,:to_hash,:to_h,:to_a,:inspect,:to_s,:==,:[],:hash,:eq
l?,:fetch,:[]=,:store,:default,:default=,:default_proc,:default_proc=,:key,:i
ndex,:size,:length,:empty?,:each_value,:each_key,:each_pair,:each,:keys,:valu
es,:values_at,:shift,:delete,:delete_if,:keep_if,:select,:select!,:reject,:re
ject!,:clear,:invert,:update,:replace,:merge!,:merge,:assoc,:rassoc,:flatten,
:include?,:member?,:has_key?,:has_value?,:key?,:value?,:compare_by_identity,:c
ompare_by_identity?,:entries,:sort,:sort_by,:grep,:count,:find,:detect,:find_i
ndex,:find_all,:collect,:map,:flat_map,:collect_concat,:inject,:reduce,:partit
ion,:group_by,:first,:all?,:any?,:one?,:none?,:min,:max,:minmax,:min_by,:ma
x_by,:minmax_by,:each_with_index,:reverse_each,:each_entry,:each_slice,:each_con
s,:each_with_object,:zip,:take,:take_while,:drop,:drop_while,:cycle,:chunk,:s
lice_before,:lazy,:nil?,:===,:=~,:!~,:<=>,:class,:singleton_class,:clone,:du
p,:taint,:tainted?,:untaint,:untrust,:untrusted?,:trust,:freeze,:frozen?,:met
hods,:singleton_methods,:protected_methods,:private_methods,:public_methods,:inst
ance_variables,:instance_variable_get,:instance_variable_set,:instance_variable_def
ined?,:remove_instance_variable,:instance_of?,:kind_of?,:is_a?,:tap,:send,:publ
ic_send,:respond_to?,:extend,:display,:method,:public_method,:singleton_method,
:define_singleton_method,:object_id,:to_enum,:enum_for,:equal?,:!,:!=,:instance
_eval,:instance_exec,:__send__,:__id__]
Dikkatettiysenizmethod'larınbirkısmıArrayileaynıçünkiikisideEnumerablemodülünükullanıyor.
Şimdisıradanbaşlayalım!ÖncekiArraybölümündeanlattığımortakmethod'larıpasgeçeceğim!
rehash
Hash'ekeyolarakArrayverebiliriz.Yanih[key]=valuemantığındakeyolarakbildiğinizArraygeçebiliriz.
a=["a","b"]
c=["c","d"]
h={a=>100,c=>300}#=>{["a","b"]=>100,["c","d"]=>300}
hHash'ininkeylerinedir?
h.keys#=>[["a","b"],["c","d"]]
2key'ivarbiri["a","b"]vediğeri["c","d"]nasılyani?
Hash
106
h[a]#=>100
h[["a","b"]]#=>100
h[c]#=>300
h[["c","d"]]#=>300
Şimdiişlerikarıştıralım.aArray'ininilkdeğerinideğiştirelim.Bakalımhneolacak?
a[0]="v"#=>"v"
a#=>["v","b"]
h[a]#=>nil????????
h[a]patladı?nildöndü.İşteşimdiimdadımızaneyetişecek?
h.rehash#=>{["v","b"]=>100,["c","d"]=>300}
h[a]#=>100
to_hash,to_h,to_a,to_s
Tipdönüştürmeleriiçinkullanılırlar.to_hveto_hasheğerkendisiHashisesonuçyinekendisiolur.to_aiseHash'denArrayyapmakiçinkullanılır.Tahminedeceğinizgibito_sdeString'eçevirmekiçinkullanılır.
h={:foo=>"bar"}
h#=>{:foo=>"bar"}
h.to_hash#=>{:foo=>"bar"}
h.to_h#=>{:foo=>"bar"}
["foo","bar"].respond_to?(:to_h)#=>true
[[:foo,"bar"]].to_h#=>{:foo=>"bar"}
[["a",1],["b",2]].to_h#=>{"a"=>1,"b"=>2}
h.to_a#=>[[:foo,"bar"]]
h.to_s#=>"{:foo=>\"bar\"}"
==veeql?Eşitlik
Hashiçindekey'lerinsırasıeşitlikkontrolündeönemlideğildir.İçerikönemlidir.Eşitlikkontrolüiçinkullanılırlar.
h1={"a"=>100,"c"=>200}
h2={70=>350,"x"=>22,"y"=>11}
h3={"y"=>11,"x"=>22,70=>350}
h1==h2#=>false
h2==h3#=>true
h1.eql?(h2)#=>false
h2.eql?(h3)#=>true
Hash
107
h2ileh3keysıralarıfarklıolmasınarağmeniçerikbazındaeşittirler.
fetch
Hashiçindensorguyaparkenkullanılır.Eğerolmayankeyçağırırsanızexceptionoluşur.Bumethodgüvenlibiryöntemdir.AksitakdirdenildönervekompleksişlerdeSilentFailyanidipsizkuyuyadüşerbirtürlühatanınyerinibulamazsınız!
h={:user=>"vigo",:password=>"secret"}
putsh.fetch(:user)#"vigo"
putsh.fetch(:email)
KeyError:keynotfound::email
Kezaeğerkey'ekarşılıkyoksadefaultdeğeratamasıyapabilirsiniz:
h={:user=>"vigo",:password=>"secret"}
h.fetch(:user)#=>"vigo"
h.fetch(:email,"Notfound")#=>"Notfound"
Blockkabulettiğiiçinartistlikhareketleryapmakdamümkün:)
h={:user=>"vigo",:password=>"secret"}
h.fetch(:email){|element|"key:#{element}isnotdefined!"}#=>"key:emailisno
tdefined!"
store
Atamayapmanınfarklıbiryöntemidir.
h={:user=>"vigo",:password=>"secret"}
h.store(:email,"[email protected]")#=>"[email protected]"
h#=>{:user=>"vigo",:password=>"secret",:email=>
#yada
h[:url]="http://webbox.io"#=>"http://webbox.io"
h#=>{:user=>"vigo",:password=>"secret",:email=>
"[email protected]",:url=>"http://webbox.io"}
default,default=
Karşılığıolmayankeyleriçinvarsayılandeğeratamasıyapılmışsabunubulmakiçinyadavarsayılandeğeriatamakiçinkullanılır.Enbaştabenzerişleryaptık:
Hash
108
h=Hash.new(10)
h[:user_age]#=>10
h#=>{}
h.default#=>10
h.default(:user_weight)#=>10
yada
h=Hash.new
h#=>{}
h.default=100#=>100
h[:user_weight]#=>100
h[:foo]#=>100
key
Value'denkey'ibulmakiçinkullanılır.Eğerkey'iolmayanbirvaluekullanırsanızsonuçnildöner!
h={:user=>"vigo",:password=>"secret"}
h.key("vigo")#=>:user
h.key("foobar")#=>nil
size,length,count
Aynıişiyaparlar,ArrargibiHash'inboyunu/uzunluğunuverir.
h={:user=>"vigo",:password=>"secret"}
h.length#=>2
h.size#=>2
h.count#=>2
Key,ValueKontrollerikeys,values,values_at
TahminedeceğinizgibikeysileHash'eaitkey'leri,valuesilesadecekey'lerekarşılıkgelendeğerleri,values_atileverdiğimizkey'lereaitdeğerlerialırız.
h={:user=>"vigo",:password=>"secret",:email=>"[email protected]"}
h.keys#=>[:user,:password,:email]
h.values#=>["vigo","secret","[email protected]"]
h.values_at(:user,:password)#=>["vigo","secret"]
key?,value?,has_key?,has_value?
Hash
109
Soruişaretiilebitenmethod'larbizeherzamanBooleanyanitrueyadafalsedönerdemiştik.AcabaHash'iniçindeilgilikeyvarmı?yadavaluevarmı?
h={:user=>"vigo",:password=>"secret",:email=>"[email protected]"}
h.key?(:user)#=>true
h.has_key?(:user)#=>true
h.key?(:full_name)#=>false
h.has_key?(:full_name)#=>false
h.value?("vigo")#=>true
h.has_value?("vigo")#=>true
h.value?("lego")#=>false
h.has_value?("lego")#=>false
include?,member?
key?yadahas_key?ileaynıişiyapar.
h={:user=>"vigo",:password=>"secret",:email=>"[email protected]"}
h.include?(:user)#=>true
h.member?(:user)#=>true
empty?
Hash'iniçindeelemanvarmıyokmu?
{:user=>"vigo",:password=>"secret",:email=>"[email protected]"}.empty?#=>false
{}.empty?#=>true
all?,any?,one?,none?
Arraybölümündegörmüştük,EnumerablemodülündengelenbuözellikaynenHash'dedekullanılıyor.all?datümelemanlar,verilenkoşuldannilyadafalsedışındabirşeydönmekzorunda,aksihaldesonuçfalseoluyor:
#value'suboşolanvarmı?
{:user=>"vigo",:password=>"secret",:email=>"[email protected]"}.all?{|k,v|v.empty
?}#=>false
{:user=>"",:password=>"",:email=>""}.all?{|k,v|v.empty?}
#=>true
{:user=>"vigo",:password=>"",:email=>""}.all?{|k,v|v.empty?}
#=>false
any?deiçlerindenbirifalseyadanildönmezsesonuçtrueolur.one?dasadecebirtanesitruedönmelidir.nonedaiseblock'dakiişlemsonucuherelemaniçinfalseolmalıdır.
Hash
110
{:is_admin=>true,:notifications_enabled=>true}.all?{|option,value|value}#=>
true
{:is_admin=>true,:notifications_enabled=>false}.any?{|option,value|value}#=
>true
{:is_admin=>true,:notifications_enabled=>false}.one?{|option,value|value}#=
>true
{:is_admin=>false,:notifications_enabled=>false}.one?{|option,value|value}#
=>false
{:is_admin=>false,:notifications_enabled=>false}.all?{|option,value|value}#
=>false
{:is_admin=>false,:notifications_enabled=>false}.none?{|option,value|value}#
=>true
{:is_admin=>false,:notifications_enabled=>false}.any?{|option,value|value}#
=>false
shift
Hash'denkey-valueçiftinisilmekiçinkullanılır.Herseferindeilkkey-valueçiftinisiler.
h={:user=>"vigo",:password=>"secret",:email=>"[email protected]"}
h.shift#=>[:user,"vigo"]
h#=>{:password=>"secret",:email=>"[email protected]"}
h.shift#=>[:password,"secret"]
h#=>{:email=>"[email protected]"}
h.shift#=>[:email,"[email protected]"]
h#=>{}
delete,delete_if,keep_if
Hash'denkeykullanarakelemansilmekiçindeletemethod'ukullanılır.
h={:user=>"vigo",:password=>"secret",:email=>"[email protected]"}
h.delete(:user)#=>"vigo"
h#=>{:password=>"secret",:email=>"[email protected]"}
Blockkullanıldığında,eğerolmayanbirkeykullanılmışsa,bununlailgiliişlemyapmamızısağlar:
h.delete(:phone){|key|"-#{key}-bulunamadı?"}#=>"-phone-bulunamadı?"
delete_ifdeisedirekblockkullanarakkoşullusilmeişlemiyapabiliyoruz.
#40'danbüyüklerisilelim
h={point_a:10,point_b:20,point_c:50}#=>{:point_a=>10,:point_b=>20,:point
_c=>50}
h.delete_if{|k,v|v>40}#=>{:point_a=>10,:point_b=>20}
h#=>{:point_a=>10,:point_b=>20}
Hash
111
keep_ifisedelete_ifintamtersigibidir.Eğerblock'dakikoşultrueisekey-valueçiftinitutar,aksihaldesiler:
#20'danküçükleritutalımsadece
h={point_a:10,point_b:20,point_c:50}
#=>{:point_a=>10,:point_b=>20,:point_c=>50}
h.keep_if{|k,v|v<20}#=>{:point_a=>10}
h#=>{:point_a=>10}
invert
Hash'inkey'leriilevalue'leriniyerdeğiştirmekiçinkullanılır.
h={"a"=>100,"b"=>200}#=>{"a"=>100,"b"=>200}
h.keys#=>["a","b"]
h.invert#=>{100=>"a",200=>"b"}
merge,update,merge!
İkiHash'ibirbirylebirleştirmekiçinmergekullanılır.
h1={"a"=>100,"b"=>200}
h2={"x"=>1,"y"=>2,"z"=>3}
h1.merge(h2)#=>{"a"=>100,"b"=>200,"x"=>1,"y"=>2,"z"=>3}
h1#=>{"a"=>100,"b"=>200}
Dikkatettiysenizh1ileh2yibirleştirdikamah1inorijinaldeğerinibozmadık.Eğerbubirleşmeninkalıcıolmasınıisteseydikyaupdateyadamerge!kullanmamızgerekecekti!
h1={"a"=>100,"b"=>200}
h2={"x"=>1,"y"=>2,"z"=>3}
h1.update(h2)#=>{"a"=>100,"b"=>200,"x"=>1,"y"=>2,"z"=>3}
h1#=>{"a"=>100,"b"=>200,"x"=>1,"y"=>2,"z"=>3}
h1={"a"=>100,"b"=>200}
h2={"x"=>1,"y"=>2,"z"=>3}
h1.merge!(h2)#=>{"a"=>100,"b"=>200,"x"=>1,"y"=>2,"z"=>3}
h1#=>{"a"=>100,"b"=>200,"x"=>1,"y"=>2,"z"=>3}
replace
Hash'iniçeriğinibaşkabirHashiledeğiştirmekiçinkullanılır.AslındavarolanHash'ibaşkabirHash'eçevirmekgibidir.Nedenreplacekullanılıyor?Tamamenhafızadakiadreslemeileilgili.replacekullanıldığızaman,aynıHashkullanılıyor,yenibirHashinstance'ıyaratılmıyor.
Hash
112
h1={"a"=>100,"b"=>200,"c"=>0}
h1.__id__#=>70320602334320
Hafızadakih1Hash'ninnesnereferansı:70320602334320.Şimdirreplaceiledeğerlerinideğiştirelim:
h1.replace({"foo"=>1,"bar"=>2})
h1#=>{"foo"=>1,"bar"=>2}
h1.__id__#=>70320602334320
Referanslarıaynı:70320602334320.Eğerdirektolarakatamayapsakdıkh1gibigörünenamabambaşkayepyenibirHash'imizolacaktı.
h1={"foo"=>1,"bar"=>2}
h1.__id__#=>70216424232360
İterasyonveBlockKullanımıAynıArray'lerdekigibiHash'lerdedeiterasyonveblockkullanmakmümkün.
each,each_pair,each_value,each_key
eachveeach_pairkardeşgibidirler:
h={"a"=>100,"b"=>200,"c"=>0}
h.each{|key,value|puts"key:#{key},value:#{value}"}
h.each_pair{|key,value|puts"key:#{key},value:#{value}"}
#key:a,value:100
#key:b,value:200
#key:c,value:0
each_valuesadecevalue,each_keydesadecekeydöner.
Hash
113
h={"a"=>100,"b"=>200,"c"=>0}
h.each_value{|value|puts"value:#{value}"}
#value:100
#value:200
#value:0
h.each_key{|key|puts"key:#{key}"}
#key:a
#key:b
#key:c
each_entry,each_slice,each_cons
Hash'dekikey-valueçiftiArrayşeklindebirentryolur:
h={"a"=>100,"b"=>200,"c"=>0}
h.each_entry{|o|puts"o:#{o}"}
#o:["a",100]
#o:["b",200]
#o:["c",0]
each_sliceileentry'leriparçacıklaraayırırız:
h={"a"=>100,"b"=>200,"c"=>0}
#2'lidilimlereayırdık
h.each_slice(2){|s|puts"slice:#{s}"}
#slice:[["a",100],["b",200]]
#slice:[["c",0]]
each_consiseeach_slicegibiçalışıramafarkıörnektekigibidir:
h={"a"=>100,"b"=>200,"c"=>0}
h.each_cons(2){|s|puts"grup:#{s}"}
#grup:[["a",100],["b",200]]
#grup:[["b",200],["c",0]]
Neticede,3key-valueçiftivardı.2'ligrupladıkamasonuçeach_slicedakigibidönmedi.["b",200]tekraretti,çıktıgruplamasımutlaka2elemaniçerdi.
default_proc,default_proc=
Konununbaşındavarsayılandeğeratamasıyaparkenşöylebirörnekvermiştik:
Hash
114
h=Hash.new{|hash,key|hash[key]="User:#{key}"}
eğer;
h.default_proc#=>#<Proc:0x007f85f2250fd8@-:7>
deseydik,buHash'eaitProcugörmüşolurduk.YanibuHashiçinvarsayılanişlemprosedürünütanımlamışoldukaslında.Örneğibirazgenişletelim:
h=Hash.new{|obj,key|obj[key]=key*4}#=>{}
h[1]#=>4
h[2]#=>8
h#=>{1=>4,2=>8}
Keyolaraksayıveriyoruz,gelensayıdandavalueüretiyoruzotomatikolarak.İşleminçalışmasıiçinbiradetobjevesayıgeçmemizgerekiyorparametreolarak.Aslında;
h.default_proc.call(Array.new,9)#=>36
h.default_proc.call([],9)#=>36
h.default_proc.call({},9)#=>36
şeklindede,Hash'isankibirfonksiyongibikullanıpişleyebiliyoruz.
Dahasonra,öncedentanımladığımızbuprosedürüdeğiştirmekistersekdefault_proc=methodunukullanıyoruz:
h=Hash.new{|hash,key|hash[key]="User:#{key}"}
h.default_proc#=>#<Proc:0x007feea39bbd80@-:7>
h[1]#=>"User:1"
#Yeniprosedürveriyoruz
h.default_proc=procdo|hash,key|
hash[key]="hello#{key}"
end
h#=>{1=>"User:1"}
h[2]#=>"hello2"
h#=>{1=>"User:1",2=>"hello2"}
compare_by_identity,compare_by_identity?
Hash'inkeyvevalue'leribirbirinebenziyormu?
Hash
115
h={"a"=>1,"b"=>2,:c=>"c"}
h["a"]#=>1
h.compare_by_identity?#=>false
h.compare_by_identity#=>{"a"=>1,"b"=>2,:c=>"c"}
h.compare_by_identity?#=>true
#acabakeyilevaluebenziyormu?
h["a"]#=>nil
#buradabenzer:)
h[:c]#=>"c"
Hash
116
SymbolSymbol(sembol)Ruby'eaitözelbirnesnedir.Birtürplaceholder(yertutucu)görevindedir.:işaretiilebaşlayanherşeysemboldür.
Sembolün,değişkendenenönemlifarkıtekilolmasıdır.Yanisemboleatanandeğişkendenhafızada1adetbulunur.
user="vigo"
user.object_id#=>70122132113780
#şimdibaşkadeğeratayalım
user="bronx"
user.object_id#=>70122132113340
#object_iddeğişti!
EğerSymbolkullansaydık:
user=:vigo
user.object_id#=>420488
user=:bronx
user.object_id#=>420648
userdeğişkeninindeğeriSymbolcinsindenolduğuiçin,artıkhafızadasabitbiryerayrılmışoldubuişiçin.Değerdeğişsebilehafızadakiadreslendiğialandeğişmemişoluyor:)
StringolarakatanmışdeğişkenideSymbol'eçevirmekmümkün:
full_name="Uğur"#=>"Uğur"
full_name.to_sym#=>:Uğur
full_name==:Uğur.id2name#=>true
user_full_name=:Uğur#=>:Uğur
user_full_name.object_id#=>420428
:is_user_admin.id2name#=>"is_user_admin"
:is_user_admin.to_s#=>"is_user_admin"
Symbol'ler,değişkenlergibidirektatamayöntemiyleyani:a=1gibibirşekildeçalışmazlar.EğerbirString'denSymbolüretmekistersenizto_symmethodunukullanmanızgerekiyor.
Hafızayıidarelikullanmak,boşuboşunadeğişkenkirliğiyaratmamakgibikonulardatercihedilir.KezaHash'lerdedeKEYatamasıSymbololarakyapılıyorbutürhız/tasarrufişleriiçin.
Symbol
117
{:user=>"vigo"}
Symbol
118
Class(Sınıf)Ruby,Object-Oriented(OO)birdilolduğuiçin,methodlarıdeğişkenlerivebenzerişeyleriiçindebarındanbirtürtaşıyıcıyaihtiyaçduyar.İştebutaşıyıcıyaClassyadasınıfdiyoruz.Aslındabentürdemeyitercihediyorumsınıfyerine.
ZatenöncekikonulardaClassMethods,InstanceMethodsgibikavramlaragirmiştik.
Class'larbirbirindentüreyebilir(Haniclass.superclassşeklindeanalizleryapmıştık)
TeknikolarakbirdosyadabirdenfazlaClasstanımlamasıyapılabilir.Örneğin,my_class.rbadlıbirdosyaiçindefarklıfarklıClasstanımlamalarıolabilir;
classMyClass
end
classOtherClass
end
a=MyClass.new#=>#<MyClass:0x007ffa2b09b758>
b=OtherClass.new#=>#<OtherClass:0x007ffa2b09b3c0>
Classtekbaşınabirnesne(Obje)bubakımdaninstantiateetmesenizbile(Yania=Array.newgibi)kullanabileceğinizbirşeydir.
Class'larındiğerbirözelliğideaçıkolmasıdır.Ruby'ninbenceenharikaözelliği,built-inyanidilinçekirdeğindengelenClass'larabilemethod/propertyeklemenizmümkündür.BukonularıMonkeyPatchingkısmındadetaylıgöreceğiz.
EnbasittanımıylaClassaşağıdakigibidir:
classMerhaba
definitialize(isim)
@isim=isim
end
defselam_sana
"Selamsana,#{@isim}"
end
end
hey=Merhaba.new"Uğur"
hey.selam_sana#=>"Selamsana,Uğur"
initializemethodu,Class'danilkörnektüredildiğinde(yanibirinstanceoluşturulduğunda)tetiklenirvebirtürClassileilgiliöntanımlamalarınyapıldığıalankonumundadır.Benzerdillerdekiclassconstructor'ıgibidüşünülebilir.
Class
119
@isimiseInstanceVariableyaniClass'tantüreyennesneyeaitdeğişkendir.
selam_sanaisebuClass'ınbirmethod'udur.heydeğişkeni,MerhabaClass'ındantüremişbirInstance'dır.Merhabasınıfındakitümmethod'larinherityanimirasolarakheynesnesinegeçmiştir.
Class'ıtanımlarkenisterklasikisterblockyönteminikullanabilirsiniz.Klasikyöntem:
classPerson
end
jack=Person.new#=>#<Person:0x007fb0521a4820>
Blockise;
Person=Class.newdo
end
jack=Person.new#=>#<Person:0x007fc42c0c8648>
şeklindedir.ClassisimleriBüyükharflebaşlar.
PublicInstanceMethod'larıBirClass'tantüreyenşeyeInstancediyoruz.Ruby'deClass'larfirst-classobjectsolarakgeçeryanibirincisınıfnesnelerdir.Budaşuanlamagelir,aslındaherClass,Kernel'dangelenClassnesnesindentüremişaltsınıftır:)
allocate,newvesuperclass
superclassilgiliClass'ınkimdengeldiğini/türediğinigösterir.Benzerörneklerikitabınbaşındayapmıştık:
String.superclass#=>Object
Object.superclass#=>BasicObject
BasicObject.superclass#=>nil
newiseönceallocatemethod'unuçağırıphafızadagerekenyeriayırır,yaniinstantiateedeceğimizClass'ınsınıfınıorganizeeder,sonraoluşacakClass'ıninitializemethod'unuçağırıpvarsailgiliargümanlarıpaseder.Her.newçağırıldığındabuişolur.
PrivateInstanceMethod'larıinherited(subclass)
Class
120
İlgilisınıfınaltsınıfıoluşturulduğundatetiklenir.
classAnimal
defself.inherited(subclass)
puts"Yenisubclass:#{subclass}"
end
end
classCat<Animal
end
classTiger<Cat
end
#Yenisubclass:Cat
#Yenisubclass:Tiger
Animal(hayvan)sınıfından,Cat(kedi)ürettik,Tiger(kaplan)'ıdayineCat(kedi)'denürettik...
Accessors(getter+setter)Özelmethod'larkullanarakMetaProgrammingmantığıylaRuby,InstanceVariable'larıyönetmeyikolaylaştırır.YukarıdakiMerhabaClass'ındaki@isimiçinaslındagetvesetyaniokuveyazmethod'larıtanımlamamızlazımkiilgilideğişkenüzerindeişlemyapabilelim.Önceuzunyolu,sonradoğruvekısayolugörelim:
classPerson
defname
@name
end
defname=(name)
@name=name
end
end
vigo=Person.new#=>#<Person:0x007f903b8d0590>
vigo.name#=>nil
vigo.name="Uğur"#=>"Uğur"
vigo.name#=>"Uğur"
namemethod'unuçağırıncabizeinstancevariableolan@namedönüyor.İlkandasetetmediğimizyanideğeratamadığımıziçinnilgeliyor.Dahasonravigo.name="Uğur"diyerekatamayapıyoruzveartıkdeğerinibelirlemişoluyoruz.Buişiçin2tanemethodyazdık.namevename=method'ları.
İştebunoktadaaccessorsimdadımızayetişiyor:
Class
121
classPerson
attr_accessor:name
end
vigo=Person.new#=>#<Person:0x007fb7c9a4c620>
vigo.name#=>nil
vigo.name="Uğur"#=>"Uğur"
vigo.name#=>"Uğur"
attr_accessor:namedediğimizde,Ruby,bizimiçinnamevename=method'larıoluşturuyor.Kezasadecebununlakalmayıp,pekçokfarklıkullanımimkanlarısunuyor.
attrmodülüyle:
attrattr_accessorattr_readerattr_writer
gibiözelgetter/setter'largeliyor.Yukarıdakiörneğiattrileyapalım;
classPerson
attr:name,true
end
Person.instance_methods-Object.instance_methods#=>[:name,:name=]
Otomatikolarak2methodekledi:[:name,:name=].Aynışeyiattr_accessor:nameiledeyapabilirdik:
classPerson
attr_accessor:name
end
Person.instance_methods-Object.instance_methods#=>[:name,:name=]
Eğersadeceattr_readerkullansaydık,sadeceilgiliinstancevariable'ınıokuyabiliramadeğerinisetedemezdik!
Class
122
classPerson
attr_reader:name
end
Person.instance_methods-Object.instance_methods#=>[:name]
vigo=Person.new
vigo.name#=>nil
vigo.name="Uğur"#=>NoMethodError:undefinedmethod`name='for#<Person:0x007ffe4
d0e8528>
GördüğünüzgibiNoMethodErrorhatasıaldıkçünkisetteryaniname=method'uoluşmadı!Pekisadeceattr_writerolsaydı?
classPerson
attr_writer:name
end
Person.instance_methods-Object.instance_methods#=>[:name=]
vigo=Person.new
vigo.name="Uğur"#=>"Uğur"
vigo.name#=>NoMethodError:undefinedmethod‘name’for#<Person:0x007fb92b9d45b8@n
ame="Uğur">
Setedebiliyoruzamagetedemiyoruz!Pekiattr_writerneredeişimizeyarar?ÖrneğinsadeceClass'ıinitializeederkendeğerpasedipsınıfiçindebirdeğişkeneatamayapmakgerektiğindekullanabilirsiniz:
classPerson
attr_writer:name
definitialize(name)
@name=name
end
defgreet
"Hello#{@name}"
end
end
vigo=Person.new"Uğur"
vigo.greet#=>"HelloUğur"
@namedeğişkeninisadeceilktetiklenmedesetediceksemvedışarıdanokumaihtiyacımyoksabuşekildekullanabilirim!
ClassVariables
Class
123
@@ilebaşlayandeğişkenlerClassVariable(SınıfDeğişkeni)olaraktanımlanır.YaniAnaClass'aaitbirdeğişkendir.Heryeniinstanceoluştuğundabudeğeraitolduğuüstsınıftanerişilebilir:
classPerson
attr_accessor:name
@@amount=0
definitialize(name)
@@amount+=1
@name=name
end
defgreet
"Hello#{name}"
end
defhow_many_people_created
"Numberofpeople:#{@@amount}"
end
end
user1=Person.new"Uğur"
user2=Person.new"Yeşim"
user3=Person.new"Ezel"
Person.class_variable_get(:@@amount)#=>3
user3.how_many_people_created#=>"Numberofpeople:3"
ClassMethodsİlgiliClass'dantüretmeyapmadan,direkClass'dançağırılanözelmethod'dur.Bumethod'uçağırmakiçinsınıftanherhangibirtüretmeyapmayagerekolmaz,direktolaraksınıf'tançağırılır:
Class
124
classPerson
attr_accessor:name
@@amount=0
definitialize(name)
@@amount+=1
@name=name
end
defgreet
"Hello#{name}"
end
defhow_many_people_created
"Numberofpeople:#{@@amount}"
end
defself.how_many_people_created
"Wehave#{@@amount}copie(s)"
end
end
user1=Person.new"Uğur"
user2=Person.new"Yeşim"
user3=Person.new"Ezel"
Person.how_many_people_created#=>"Wehave3copie(s)"
Person.how_many_people_createddirektolarakçağırılır!
SingletonsSınıfiçindeclasskomutunukullanarakmethodoluşturmakiçindir.BunaSingletondenir.Sadecebirkereinstantiate(tetiklenmediyelim)olur.Örneğinalanhesabıyapacakbirsınıfdüşünüyoruzvebununcalculatemethod'uolsun.EnxBoybizemetrekare'yiversin:
classArea
class<<self
defcalculate(width,height)
width*height
end
end
end
Area.calculate(5,5)#=>25
GördüğünüzgibihiçbirşekildenewyadabenzerbirşeytüretmekullanmadıkdirektolarakArea.calculate(5,5)şeklindekullandık.Kezaaynıişi;
Class
125
classArea
end
x=Area.new
defx.calculate(width,height)
width*height
end
x.calculate5,5#=>25
şeklindedeyapabilirdik.
Inheritance(Miras)Aslındabudabildiğimizbirşey.Sınıftantüremeyaparkan,türettiğimizsınıfınözellikleritüreyenemirasgeçer.
classAnimal
attr_accessor:name,:kind
definitialize(name)
@name=name
end
defsay_hi
"Hello!I'ma#{@kind},mynameis#{@name}"
end
end
classCat<Animal
end
classHorse<Animal
end
bidik=Cat.new"Bıdık"
bidik.kind="cat"
zuzu=Horse.new"Zuzu"
zuzu.kind="horse"
bidik.say_hi#=>"Hello!I'macat,mynameisBıdık"
zuzu.say_hi#=>"Hello!I'mahorse,mynameisZuzu"
CatveHorseAnimalsınıfından<yöntemiyletürediveAnimaldekitümmethod'larCatveHorse'ageçti.
Class
126
AccessLevel(Erişim):Public,Private,veProtectedMethod'larClassiçindekimethod'lardurumagöreerişilebilirlikaçısındankısıtlanabilir.publicolanlarheryerdenerişilebilirken(budefaultbirdurumdur),privateolanasadeceiçeridenerişilebilir,protectedolanaiseancakaltsınıftantüreyendenerişilebilir.
classUser
defbu_sayede_private_cagirabilirim
bu_sadece_iceriden
end
private
defbu_sadece_iceriden
puts"Buprivatemethod.Bumethodinstance'dançağırılamaz!"
end
protected
defbu_sadece_subclass_veya_instance_dan
puts"Buprotecedmethod."
end
end
u=User.new
u.bu_sadece_iceriden#=>NoMethodError:privatemethod‘bu_sadece_iceriden’calledfo
r#<User:0x007feb9d0d2560>
Gördüğünüzgibibu_sadece_iceridenmethod'unuUserdaninstantiateettiğimizuüzeridençağıramıyoruz.privateolduğuiçinancakiçeridençağırılabilir:
u.bu_sayede_private_cagirabilirim#=>"Buprivatemethod.Bumethodinstance'dançağı
rılamaz!"
publicolanbu_sayede_private_cagirabilirimmethod'uiçeridenprivatemethodolanbu_sadece_iceriden'eerişebildi.Pekiyaprotected?Eğerdirektolarakçağırmayakalksaydık:
u.bu_sadece_subclass_veya_instance_dan#=>NoMethodError:protectedmethod‘bu_sadece
_subclass_veya_instance_dan’calledfor#<User:0x007fff131c60a0>
Hemengerekeniyapalım;UserClass'ındanbaşkabirClassüretelim:
Class
127
classSuperUser<User
definitialize
bu_sadece_subclass_veya_instance_dan
end
end
y=SuperUser.new#=>"Buprotecedmethod."
MethodAliasingBazıdurumlarda,üstsınıftakimethod'uezmekgerekir.Buişlemiyaparkenaslındaüstsınıftakiorijinalmethod'adaerişmenizgerekebilir.
classUser
attr_accessor:name
definitialize(name)
@name=name
end
defgive_random_age
(20..45).to_a.sample
end
end
classSuperUser<User
alias:yedek:give_random_age#üstsınıftakigive_random_age’isakladık,yedekadın
ıverdik
defgive_random_age
rnd=self.yedek
"Kendiyaşım:43,rnd=#{rnd}"
end
end
u=User.new"vigo"
u.name#=>"vigo"
u.give_random_age#=>29
v=SuperUser.new"Uğur"
v.give_random_age#=>"Kendiyaşım:43,rnd=44"
Örnekte,SuperUserClass'ındakafamızagöregive_random_agemethod'unuezipkendiişlemimiziyaparken,üstsınıftanmirasgelenorijinalmethod'udayedekliyoruz,yedekadıaltında.
SınıflarAçıktır,ModifiyeEdilebilir!
Class
128
İsterKernel'danisterbaşkabiryerdengelsin,herşekildeClass'larmodifiyeedilebilir.DetaylarıMonkeyPatching'degöreceğiz.Kısabirörnekyapalım.StringClass'ınaneşemizegörebirmethodekleyelim:
classString
defhello
"Hello:#{self}"
end
end
"Deneme".hello#=>"Hello:Deneme"
TipiStringolanherşeyinartıkhellodiyebirmethod'uoldu:)
NestedClassAynıModule'lerdeolduğugibi,içiçeClasstanımlamakdamümkündür.Kimizamandüzenliolmakiçin(Namespace)kimizamandabellibirkuralıuygulamakiçinkullanılır;
Class
129
classAnimal
attr_reader:name
definitialize(name)
@name=name
end
classCat<Animal
end
classHorse<Animal
end
classUber
end
end
horse=Animal::Horse.new"Furry"
horse.name#=>"Furry"
horse.class#=>Animal::Horse
horse.class.superclass#=>Animal
cat=Animal::Cat.new"Bıdık"
cat.name#=>"Bıdık"
cat.class#=>Animal::Cat
cat.class.superclass#=>Animal
alien=Animal::Uber.new
alien.respond_to?(:name)#=>false
alien.class#=>Animal::Uber
alien.class.superclass#=>Object
CatveHorse,Animalsınıfındantüremiş,UberisesadeceAnimalnamespace'iiçindeolupkendibaşınabirClass'ıtemsiletmektedir.
Class
130
ModuleClass'abenzeyenamaClassgibiinstantiateedilemeyenşeydirmodül.ModüldenenşeyeClasseklenebilir(includeedilir)ModüldengelenmethodlarartıkilgiliClass'ınmethoduhalinegelir.
YanidüşününkibirClassvar,buClass'ınfarklı2-3Class'tanözellikalmasınıistiyorsunuz.BunubaşarmakiçinilgiliClass'ao2-3Class'ıModülolarakekliyorsunuz!
Module'lersayesindeNamespaceveMix-infonksiyonalitesidegelmişolur.
TahminedebileceğinizgibimodulekelimesiylebaşlarlarveaynıClass'lardaolduğugibibüyükharflebaşlayanmoduleadıyadaNamespacetanımlamasıyapılır:
moduleRandomNumbers
defgenerate
rand(10)
end
end
classDiceGame
includeRandomNumbers
end
classRaceGame
includeRandomNumbers
end
g=DiceGame.new
g.generate#=>3
x=RaceGame.new
x.generate#=>7
RandomNumbersadındabirModuleyaptık,ikifarklıClass'ımızvar,DiceGameveRaceGamediye,includeilebuModule'ü2farklıClass'aekledik.ŞimdiherikiClass'ındagenerateadındamethod'uoldu...
NamespacingModuleiçindeModuletanımlayabilirsiniz.BusayedebelirlediğinizModuletanımıaltındabaşkaaltModule'lervemethod'larekleyebilir,busayedetümfonksiyonaliteyiortakbirisimaltındanyürütebilirsiniz:
Module
131
moduleFramework
moduleHttpFunctions
defself.fetch_url
"Thisisurlfetcher"
end
end
end
Framework::HttpFunctions.fetch_url#=>"Thisisurlfetcher"
AltModule'eulaşmakiçin::kullandık.Aynıkoduşuşekildedetanımlayabilirdik:
moduleFramework
end
moduleFramework::HttpFunctions
defself.fetch_url
"Thisisurlfetcher"
end
end
Framework::HttpFunctions.fetch_url#=>"Thisisurlfetcher"
Busayede,başkabirkütüphanedengelenModule'eekModule'lertakmaşansınızolur.ÖrneğinSinatraiçinekbirözellikyapıyorsunuz.Budurumda;
moduleSinatra::MyFeature
end
Şeklindekullanabilirsiniz.
Scope(KapsamaAlanı)DikkatettiysenizModule'ükullanırkenClassgibiinstanciateetmedik.Kezaörnekteself.fetch_urldiyemethodtanımlamasıyaptık.AslındaburadaSingletongibikullandık.Örnektefetch_urlmethoduiçinscopeolarakHttpFunctionsvermişolduk.Yanifetch_urlsadeceFramework::HttpFunctions.fetch_urlşeklindeerişilebiliroldu.
Constants(Sabitler)Moduleiçindesabitdeğertanımlamasıdayapmakmümkündür.
Module
132
moduleA
SABIT=5
end
A::SABIT#=>5
Eğernested(içiçe)yaniModuleiçindeModuleyaparsak,sabitlereaşağıdakigibierişebiliriz:
moduleA
SABIT=5
moduleB
defself.sabit_degeri_ver
SABIT
end
end
end
A::SABIT#=>5
A::B.sabit_degeri_ver#=>5
Peki,dışarıdatanımlanmışbirsabitvarsa?
SABIT=5#endıştakiglobal
moduleA
SABIT=10#içerideki
moduleB
defself.sabit_degeri_ver
"#{::SABIT},#{SABIT}"
end
end
end
A::B.sabit_degeri_ver#=>"5,10"
Endıştakini::SABITilealdık.
Visibility,AccessLevel(Erişim):AynıClass'lardakigibipublic,privateveprotectedolayıModule'leriçindegeçerlidir.
Module
133
moduleA
defsadece_iceriden
"Buprivatemethod"
end
defbu_sayede_private_erisim_olur
sadece_iceriden
end
private:sadece_iceriden
end
classDeneme
includeA
end
c=Deneme.new
c.sadece_iceriden#=>NoMethodError:privatemethod‘sadece_iceriden’calledfor#<De
neme:0x007f8f7c9188c8>
c.bu_sayede_private_erisim_olur#=>"Buprivatemethod"
ExtendveIncludeDurumlarıRuby'debirClasssadecetekbirClass'tantüreyebildiğiiçinmoduleveincludeçözümlerindenbahsetmiştik:
modulePerson
attr_accessor:name
defsay_hi
"Hello#{@name}"
end
end
Person#=>Person
classUser
includePerson
definitialize(name)
@name=name
end
end
User#=>User
u=User.new("Uğur")#=>#<User:0x007fcd42976de8@name="Uğur">
u.say_hi#=>"HelloUğur"
u.name="vigo"
u.say_hi#=>"Hellovigo"
Module
134
Personmodülündengelensay_himethod'una;
User.new("Ezel").say_hi#=>"HelloEzel"
erişebiliyorsunuzama;
User.say_hi#=>undefinedmethod`say_hi'forUser:Class(NoMethodError)
yaptığımızdaolmayanbirmethodçağrımıyapmışoluruz.Eğerincludeyerineextendkullansaydık;
modulePerson
attr_accessor:name
defsay_hi
@name||="Undefinedname"
"Hello#{@name}"
end
end
classUser
extendPerson
definitialize(name)
@name=name
end
end
user=User.new("Yeşim")#=>#<User:0x007f87c39702a0@name="Yeşim">
user.name#=>undefinedmethod`name'for#<User:0x007f87c39702a0@name="Yeşim">(NoM
ethodError)
ÇünkiPersonaaitözelliklerieklemek(include)yerineextend(genişletme)ettikve;
User.say_hi#=>"HelloUndefinedname"
User.instance_methods-Object.instance_methods#=>[]#boşarray
say_hiartıkbirsingletonhalinegeldiyaniInstanceMethod'uolmakyerineClassMethod'uoldu.Zatenilgilisınıfınvarolanmethod'larınabaktığımızdaboşArraydöndüğünügörürüz.
Özetle,includeilesankibaşkabirsınıftantürergibitümözellikleriinstancemethodolarakalırken,extendkullandığımızdadirekClasskopyasıgibidavranıyor.
Modüldengelenmethod'larıClassiçindeinstancemethodgibikullanmakyerinesingletonmethodolarakkullanacağınızzamanextendkullanabilirsiniz!
Module
135
Module
136
Bölüm5Bubölümde;
EnumerationveIterationRangesFileSystemveIO(DosyaSistemi)ExceptionHandlingKernelModülü
konularınıişleyeceğiz.
Bölüm5
137
EnumerationveIterationSayılabilennesnelerEnumeratorsınıfındantüremişlerdirveiçindedöngü/tekraryapılabilennesnelerhalinegeldikleriiçindeIterablehalegelmişlerdir.Yaninedemekistiyorum?
["a","b","c"].class#=>Array
["a","b","c"].each.class#=>Enumerator
["a","b","c"]aslındabirArrayiken,#eachmethod'unuçağırdığımızandaelimizdekiArraybirdenEnumeratorhalinegeldiveiçindeiterasyonyapılabilecekyanitekertekerdiziiçindekielemanlaraerişipistediğimizigibikullanabileceğimizbirhalegeldi.
each_with_object,with_object
İkimethod'daaynıişiyapar.ElimizdeEnumeratorvarsa,yanibuiçindedolaşılabilenbirnesneise,buiterasyonaaraelementlertakabiliriz.
Buikimethod,Enumerator'dekiherelemanaverilenşeyitakar.Aşağıdakiörnekteeach_with_object("foo"),["a","b","c"]dizisindekiherelemaniçindir.Dolayısıyla,buişlemsonrasındaneolduğunuanlamakiçinEnumeratorüto_amethod'uileArrayeçevirdik.
enumerator=["a","b","c"].each
enumerator_with_foo=enumerator.each_with_object("foo")
enumerator_with_foo.to_a#=>[["a","foo"],["b","foo"],["c","foo"]]
Keza,budurumdaenumerator_with_foodaeachmethod'unukullanarak,each_with_objectilepasedilennesneyedeiterasyonesnasınaulaşabiliyoruz;
enumerator=["a","b","c"].each
enumerator_with_foo=enumerator.each_with_object("foo")
enumerator_with_foo.eachdo|element,obj|
puts"eleman:#{element},obj:#{obj}"
end
#eleman:a,obj:foo
#eleman:b,obj:foo
#eleman:c,obj:foo
ElimizdeEnumeratorvarsa,birşekildesıra/indexbilgisidevardemektir;
EnumerationveIteration
138
sayilar=[1,2,3,4].each
sayilar.next#=>1
sayilar.next#=>2
sayilar.next#=>3
sayilar.next#=>4
sayilar.next#=>StopIterationhatası!
nextmethod'unukullanaraksonrakielemanaulaşabiliyoruz.Hatırlarsanız,Array'ler0index'lidir.ElimizdekiArrayiçindedolaşırkenindexkullanmakistersekeach_with_indexmethod'unukullanırız;
["Uğur","Yeşim","Ezel","Ömer"].each_with_indexdo|name,index|
puts"İsim:#{name},index:#{index}"
end
#İsim:Uğur,index:0
#İsim:Yeşim,index:1
#İsim:Ezel,index:2
#İsim:Ömer,index:3
Kezaforkullanarakdaaşağıdakigibibirişlemyapabiliriz;
isimler=["Uğur","Yeşim","Ezel","Ömer"]
forisiminisimler
puts"isim:#{isim}"
end
#isim:Uğur
#isim:Yeşim
#isim:Ezel
#isim:Ömer
next_values,peek,peek_values,rewind
AynınextgibiçalışırfakatgeriyeArraydönerveilgiliindexpozisyonunuileritaşır.SonageldiğindedeStopIterationhatasıverir(Exception)
a=[1,2,3,4].each
a.next#=>1
a.next_values#=>[2]
a.next_values#=>[3]
peekilenextdensonrakideğerigörürüz.EğersonagelinmişseyineStopIterationraiseedilir.
EnumerationveIteration
139
a=[1,2,3,4].each
a.next#=>1
a.peek#=>2
a.next#=>2
a.peek#=>3
a.next#=>3
a.peek#=>4
a.next#=>4
a.peek#=>StopIteration:iterationreachedanend
aynınext_valuesgibipeek_valuesdebizeArrayolarakbilgiverirnextsonrasındakalanelemanları.
rewindilepozisyonubaşaalırız,yanikaydıgerisararız:)
a=[1,2,3,4].each
a.next#=>1
a.next#=>2
a.next#=>3
a.rewind#=>#<Enumerator:[1,2,3,4]:each>
a.peek_values#=>[1]
a.next#=>1
DiğerNesnelerdekiEnumerationDurumları
Fixnum
upto,downto,times
Birsayıdanyukarıdoğrusayarkenupto,aşağıdoğrusayarkendowntovekaçdefaaynıişlemiyaparkendetimeskullanırız.
EnumerationveIteration
140
#10'dan5'esayıyoruz,10'da5'dedahil..
10.downto(5){|i|puts"Sayı:#{i}"}
#>>Sayı:10
#>>Sayı:9
#>>Sayı:8
#>>Sayı:7
#>>Sayı:6
#>>Sayı:5
#5'den10'asayıyoruz,10'da5'dedahil..
5.upto(10){|i|puts"Sayı:#{i}"}
#>>Sayı:5
#>>Sayı:6
#>>Sayı:7
#>>Sayı:8
#>>Sayı:9
#>>Sayı:10
#3defablockiçindekikodçalışsın
#0'dan3'ekadar3hariç:)
3.times{|i|puts"#{i}"}
#>>0
#>>1
#>>2
String
AynımantıktauptovedowntoilginçbirşekildeStringiçindekullanılır.ÖrneğinA'danitibarenM'yekadardemekiçin:
"A".upto("M"){|s|putss}
#>>A
#>>B
#>>C
#>>D
#>>E
#>>F
#>>G
#>>H
#>>I
#>>J
#>>K
#>>L
#>>M
yada,"AB","AC","AD"gibisekansolarakgitmekgerektiğindede;
EnumerationveIteration
141
"AB".upto("AE"){|s|putss}
#>>AB
#>>AC
#>>AD
#>>AE
tamtersiiçindowntokullanılır.
EnumerationveIteration
142
RangesBaşı,sonuolan,tanımlananbellibiraralıktakideğerlerigösterennesnelerRangesınıfındadır.Örneğin0'la5arasındakisayılarRangeolarakifadeedilebilir;
(0..5)#=>0..5
(0..5).class#=>Range
(0..5).to_a#=>[0,1,2,3,4,5]
(0..5).to_a.join#=>"012345"
(0..5).each#=>#<Enumerator:0..5:each>
(0..5)ifadesinde0ve5dahilolmaküzerebiraralıktanımladık.İstediğimizgibiişleyebiliriz.
(-10..0).to_a#=>[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0]
(0..-10).to_a#=>[]
("a".."e").to_a#=>["a","b","c","d","e"]
Eğer..yerine...kullanırsak,yani(0..5)dersek,5hariçdemişoluruz;
(0...5).to_a#=>[0,1,2,3,4]
("a"..."e").to_a#=>["a","b","c","d"]
Sondeğerhariçmidahilmianlamakiçinexclude_end?method'unukullanırız;
(5..10).exclude_end?#=>false
(5...10).exclude_end?#=>true
RangeaslındabirClass'dırveherClassgibi;
r=Range.new(0,2)#=>0..2
r.to_a#=>[0,1,2]
kullanılabilir.==yadaeql?method'uilekarşılaştırılabilir;
(0..2)==(0..2)#=>true
(0..2).eql?(0..2)#=>true
(0..2)==(0...2)#=>false
(0..2)==Range.new(0,2)#=>true
(0..2).eql?(Range.new(0,2))#=>true
begin,first,cover?,include?,member?,end,last
Ranges
143
Aralığınbaşlamadeğerinialmakiçinbeginyadafirstkullanabildiğimizgibi,first'eparametregeçerek,ilkNdeğerideokuyabiliriz;
(5..10).begin#=>5
(5..10).first#=>5
(5..10).first(2)#=>[5,6]#ilk2değeriver
Belirlediğimizaralıkiçindesorguyapmakiçincover?yadainclude?yadamember?method'unukullanırız.cover?kullanırkeneğerverdiğimizdeğeraralıkiçindeysesonuçtruedöner;
(5..10).cover?(6)#=>true
(5..10).cover?(4)#=>false
(5..10).cover?(11)#=>false
(5..10).cover?(9)#=>true
("a".."z").cover?("b")#=>true
("a".."z").cover?("1")#=>false
("a".."z").cover?(1)#=>false
("a".."z").cover?("abc")#=>true
include?ilecover?arasındakifarkiseşudur;cover?averilenparametredekideğer,örnektekiabctekertekerrangeiçindevarmı?yaniavarmı?bvarmı?cvarmı?şeklindeolurken,include?daabcvarmı?şeklindedir;
("a".."z").cover?("abc")#=>true
("a".."z").include?("abc")#=>false
("a".."z").cover?("a")#=>true
("a".."z").include?("a")#=>true
Tahminedeceğinizgibi,endilesondeğerialırız.
(5..10).end#=>10
(5...10).end#=>10
lastiledeaynıfirstdekigibisonyadasonNdeğeriokuruz;
(5..10).last#=>10
(5..10).last(3)#=>[8,9,10]
min,max,size
minvemaxiletanımlıaralıktakienbüyük/küçükdeğerialırız,sizebizeboyuverir;
Ranges
144
(5..10).min#=>5
(5..10).max#=>10
(5..10).size#=>6
stepilekaçarkaçarartacağınıveririz;
r=Range.new(0,5)
r.step(2)#=>#<Enumerator:0..5:step(2)>
r.step(2).to_a#=>[0,2,4]
Ranges
145
FileSystemveIO(DosyaSistemi)
FileIOsınıfındanözellikleriçerenFilesınıfı,fizikidosyalarlaişlemyapmamızısağlayanözelliklerisunarbize.Ruby'ninüzerindeçalıştığıişletimsisteminegöredefilepermissionyanidosyaüzerindekiyetkisistemidedevrededir.
DefaultolarakgelenConstant'ları:
File.constants#=>[:Separator,:SEPARATOR,:ALT_SEPARATOR,:PATH_SEPARATOR,:Constan
ts,:Stat,:WaitReadable,:WaitWritable,:EAGAINWaitReadable,:EAGAINWaitWritable,:EW
OULDBLOCKWaitReadable,:EWOULDBLOCKWaitWritable,:EINPROGRESSWaitReadable,:EINPROGRES
SWaitWritable,:SEEK_SET,:SEEK_CUR,:SEEK_END,:RDONLY,:WRONLY,:RDWR,:APPEND,:CRE
AT,:EXCL,:NONBLOCK,:TRUNC,:NOCTTY,:BINARY,:SYNC,:DSYNC,:NOFOLLOW,:LOCK_SH,:L
OCK_EX,:LOCK_UN,:LOCK_NB,:NULL,:FNM_NOESCAPE,:FNM_PATHNAME,:FNM_DOTMATCH,:FNM_C
ASEFOLD,:FNM_EXTGLOB,:FNM_SYSCASE]
File::ALT_SEPARATOR#=>nil#BuRuby’ninçalıştığıplatformaözeldir
File::PATH_SEPARATOR#=>":"
File::SEPARATOR#=>"/"
File::Separator#=>"/"
ÖrneğinWindows'daçalışanRuby'deSEPARATORtersslash\şeklindegelecektir.
PublicClassMethod'larıabsolute_path,expand_path,join,split
Stringolarakverilenpathbilgisiniabsolutepath'eçevirir.EğerikinciparametreverilmezseCWD(currentworkingdirectory)yanioaniçiniçindeçalıştığınızdirectorybilgisikullanılır.
File.absolute_path("~")#=>"/~"
File.absolute_path(".gitignore","~")#=>"/~/.gitignore"
expand_pathdebirneviabsolutepath'eçevirir:
File.expand_path("~/.gitignore")#=>"/Users/vigo/.gitignore"
Kezadahakomplekspathbulmaişlerindedekullanılır.Budurumda__FILE__sabitihayatımızıkolaylaştırır.OanRubyscript'ininçalıştığıdosyanınpath'i__FILE__sabitindedir.Örneğinaşağıdakigibibirdirectoryyapısıolsa:
FileSystemveIO(DosyaSistemi)
146
proje/
├──lib
│└──users.rb
└──main.rb
velib/users.rbiçinden,dışarıdabulunanmain.rbdosyasınınpath'ineulaşmakistesek;
File.expand_path("../../main.rb",__FILE__)
şeklindekullanırız.
joinkullanarak,Ruby'ninçalıştığıişletimsisteminebağlıolarak,File::SEPARATORkullanarakgeçilenstring'leribirleştiririz:
File.join("usr","local","bin")#=>"usr/local/bin"
Dizinvedosyaayrıştırmasınıdasplitileyaparız:
File.split("usr/local/bin/foo")#=>["usr/local/bin","foo"]
atime,ctime,mtime
Dosyayasonerişilentarihiatimeile,dosyadayapılmışolansondeğişikliktarihinidectimeile,sondeğişiklikzamanınıdamtimeilealırız.
File.atime("/Users/vigo/.gitignore")#=>2014-11-0511:45:10+0200
File.ctime("/Users/vigo/.gitignore")#=>2014-08-0411:33:14+0300
File.mtime("/Users/vigo/.gitignore")#=>2014-10-2915:05:15+0200
basename,dirname,extname
Pathiçindendosyaadınıalmakiçinbasenamekullanırız.Eğerparametreolarakatacağımızşeyi(örneğinextensionolarak.gif,.rbgibi)geçersekbizesadecedosyanınadınıverir.
File.basename("/Users/vigo/test.rb")#=>"test.rb"
File.basename("/Users/vigo/test.rb",".rb")#=>"test"
Buişintersinidedirnameileyaparız,yanidirectoryadıgerekince:
File.dirname("/Users/vigo/test.rb")#=>"/Users/vigo"
şekindekullanırız.Dosyanınextension'ınıöğrenmekiçinextnamekullanırız.
FileSystemveIO(DosyaSistemi)
147
File.extname("test_file.rb")#=>".rb"
File.extname("/foo/bar/test_file.rb")#=>".rb"
File.extname("test_file")#=>""
chmod,chown,lchmod,lchown
HerikikomutdaUnix'dengelir.ChangemodveChangeownerişleriniyapmamızısağlar.chmodileUnixizinleriniayarlarız:
-rw-r--r--1vigowheel0Aug3019:19file-01.txt
||||||||||
|||||||||+---Others,Execute(x)1=2^0
||||||||+----Others,Write(w)2=2^1
|||||||+-----Others,Read(r)4=2^2
||||||+------Group,Execute(x)1=2^0
|||||+-------Group,Write(w)2=2^1
||||+--------Group,Read(r)4=2^2
|||+---------Owner/UserExecute(e)1=2^0
||+----------Owner/UserWrite(w)2=2^1
|+-----------Owner/UserRead(r)4=2^2
+------------IsDirectory?(d)
file-01.txtdosyasında,User(yanidosyanınsahibi)ReadveWritehakkınasahiptir.GroupveOthersisesadeceReadhakkınasahiptir.Budurumdavarolanbudosyaninchmoddeğeri:
Owner/User:Read,Write=>4+2=6
Group:Read=>4=4
Others:Read=>4=4
----------------------------------------
644unixfilepermission
şeklindedir.HattaTerminal'den;stat-f'%A'file-01.txtyaparsak644olduğunudagörebiliriz.ŞimdibudosyayıRubyilesadecesahibitarafındanokunurveyazılıryapıp,başkahiçbirkimsetarafındanokunamazveyazılamazhalegetirelim:
File.chmod(0600,"file-01.txt")
Kezadosyanınsahibinidedüzenlemekiçinchownkullanırız.AynıterminaldekigibiKULLANICI:GRUPşeklinde,toplamdaüçparametregeçeriz.İlkikullanıcıyıbelirler.nilyada-1geçtiğimiztaktirdeilgilişeyisetetmemişoluruz.Yanisadecegrubudeğiştireceksekkullanıcıiçinnilyada-1geçebiliriz.
File.chown(nil,20,"/tmp/file-01.txt")#=>1
GrupIDolarak20geçtik,OSX'dekiid20karşılıkolarakstaffgrubunadenkgelir.
FileSystemveIO(DosyaSistemi)
148
lchmodvelchownilenormalchmod,chownfarkı,lilebaşlayanlarsemboliklinkleritakipetmezler.
ftype,stat,lstat,size
Dosyanınnetürbirdosyaolduğunuftypeileanlarız:
File.ftype("/tmp/file-01.txt")#=>"file"
File.ftype("/usr/")#=>"directory"
File.ftype("/dev/null")#=>"characterSpecial"
statileaynenbirazönceshell'denyaptığımız(stat-f'%A'file-01.txt)gibiaynıişiRuby'dendeyapabiliriz:
File.stat("/tmp/file-01.txt")#=>#<File::Statdev=0x1000004,ino=1540444,mode
=0100600,nlink=1,uid=501,gid=20,rdev=0x0,size=4,blksize=4096,blocks=8,atime=20
14-11-1214:41:49+0200,mtime=2014-11-1214:40:13+0200,ctime=2014-11-1214:45:28+0
200>
File.stat("/tmp/file-01.txt").uid#=>501
File.stat("/tmp/file-01.txt").gid#=>20
File.stat("/tmp/file-01.txt").mtime#=>2014-11-1214:40:13+0200
lstatdaaynıişiyaparfakataynılchmodvelchowndakigibisemboliklinkleritakipetmez!
Dosyanınbytecinsindenbüyüklüğünüalmakiçinsizekullanırız:
File.size("/Users/vigo/.gitignore")#=>323
delete,unlink,link,rename,readlink,symlink
Herikisidedosyasilmeyeyarar.Eğerdosyabaşarıylasilinirse1döner,aksihaldehataalırız!
File.delete("/tmp/foo.txt")#=>1yanisilindi
File.delete("/tmp/foo1.txt")#=>Nosuchfileordirectory
linkileHARDLINKoluşturuyoruz.Bunudosyanınbirkopyası/yansımasıgibidüşünebilirsiz.Orijinaldosyadeğiştikçelinklenmişdosyadagünceliçeriğesahipolur.Link'inhangidosyayabağlıolduğunudareadlinkileokuruz:
File.link("orijinal_dosya","linklenecek_dosya")
File.readlink("linklenecek_dosya")#=>"orijinal_dosya"
Semboliklinkyanisymlinkiçin;
FileSystemveIO(DosyaSistemi)
149
File.symlink("foo.txt","bar.txt")#=>0
File.readlink("bar.txt")#=>"foo.txt"
Komutsatırındanbakınca;
-rw-r--r--1vigowheel0Dec1316:08foo.txt
lrwxr-xr-x1vigowheel7Dec1316:08bar.txt->foo.txt
şeklindebar.txtdosyasınınfoo.txtdosyasınalinklendiğinigörürüz.
Dosyaisminideğiştirmekiçinrenamekullanırız.
File.rename("/tmp/file-01.txt","/tmp/file-01.txt.bak")#=>0
file?,directory?,executable?,exist?,identical?,readable?,size?,
Dosyagerçektenfizikibirdosyamı?yadadirectorymi?yadabudosyavarmı?
#file?
File.file?("/tmp/file-01.txt")#=>true(evet)
File.file?("/tmp/file-02.txt")#=>false
#directory?
File.directory?("/tmp/file-02.txt")#=>false
File.directory?("/tmp/test_folder")#=>true(evet)
#dosyavarmı?
File.exist?("/tmp/file-01.txt")#=>true(var)
File.exist?("/tmp/file-02.txt")#=>false
Dahaöncedosyaizinlerindenbahsetmiş,bazıdosyalarınexecutableolduğunusöylemiştik.Acabadosyaçalıştırılabiliryaniexecutablemı?
File.executable?("/tmp/file-01.txt")#=>false
-rw-r--r--1vigowheel0Nov1510:39file-01.txt
File.executable?("/tmp/execuatable_file")#=>true
-rwxr-xr-x1vigowheel0Nov1510:43execuatable_file
Executableolandosyadaxflagaktifgördüğünüzgibi:)
new,open
openmethod'uilenewaynıişiyapar.Dosyaaçmayayarar.Dosyayıaçarkenhangidurumagöreaçacağımızıyaniokumakiçinmi?yazmakiçinmi?yoksavarolandosyayaekyapmakiçinmi?belirtmemizgerekir.
FileSystemveIO(DosyaSistemi)
150
f=File.new("/tmp/test.txt","w")
f.puts"Merhaba"
f.close
/tmp/test.txtadlıbirdosyaoluşturupiçineputsileMerhabayazdık.Eğercat/tmp/test.txtyaparsanızkontroledebilirsiniz.Dikkatettiysenizmodeolarak"w"kullandık.Bumode'larneler?
Mode Açıklama
r Read-only,sadeceokumakiçin.Budefaultmode'dur.
r+ Read+write,hattaread+prepend,pointer'ıbaşaalır,yanibumethod'labişiyazarsanız,yazdığınızşeydosyanınbaşınaeklenir.
w Write-only,sadeceyazmakiçindir.Eğerdosyayoksahataverir!
w+ Read+Write,hattaread+append,pointer'ıdosyanınsonunaalırveyazdıklarınızısonaekler.Eğerdosyayoksahataverir!
a Write-only,Eğerdosyavarsapointer'ısonaalırvesonaekyapar,dosyayoksasıfırdanyenidosyaüretir.
a+ Read+write,Aynıagibiçalışır,sonaekyapar,hemokumayahemdeyazmayaizinverir.
b Binarymode
t Textmode
fnmatch,fnmatch?
FileNameMatchyanidosyaadıeşleştirmek.RegExpattern'inegöredosyaadıyakalamak/kontroletmekiçinkullanılır.2zorunluve1opsiyonelolmaküzere3parametrealabilir.Pattern,dosyaadıveopsiyonalolarakFlag'ler...
File.fnmatch('foo','foobar.rb')#=>false
File.fnmatch('foo*','foobar.rb')#=>true
File.fnmatch('*foo*','test_foobar.rb')#=>true
Şimdi;
File.fnmatch('**.rb','./main.rb')#=>false
BuişlemintruedönemsiiçinFNM_DOTMATCHflag'inikullanacağız:
File.fnmatch('**.rb','./main.rb',File::FNM_DOTMATCH)#=>true
FileSystemveIO(DosyaSistemi)
151
0:0 1:0
FNM_DOTMATCH Noktailebaşlayandosyalarda*kullanımınaizinver
FNM_EXTGLOB {a,b,c}gibipaternlerdeglobalaramayaizinver
FNM_PATHNAME Pathayraçlarında*kullanımınıengelle
FNM_CASEFOLD Casein-sensitiveyanibüyük/küçükharfayırtetme!
File::FNM_NOESCAPE ESCAPEkodukullan
File.fnmatch('*','/',File::FNM_PATHNAME)#=>false
File.fnmatch('FOO*','foo.rb',File::FNM_CASEFOLD)#=>true
File.fnmatch('f{o,a}o*','foo.rb',File::FNM_EXTGLOB)#=>true
File.fnmatch('f{o,a}o*','fao.rb',File::FNM_EXTGLOB)#=>true
File.fnmatch('\foo*','\foo.rb')#=>false
File.fnmatch('\foo*','\foo.rb',File::FNM_NOESCAPE)#=>true
IOTümgiriş/çıkış(Input/Output)işlerininkalbiburadaatar.FilesınıfıdaIO'nunaltsınıfıdır.Binaryokuma/yazmaişlemleri,multitaskingişlemler(Processspawning,asyncişler)hepbusınıfsayesindeçalışır.
Ruby101seviyesiiçinbirazkarmaşıkolsadahi,sadecefikrinizolmasıaçısından,enbilinenvekullanılanbirkaçmethod'adeğinmekistiyorum.
binread
Binaryread,yanibyte-byteokumaişlemiiçinkullanılır.Opsiyonelolarakgeçilen2.parametre,kaçbyteokumakistediğimizi,3.parametredeoffsetyanikaçbyteötedenokumayabaşlamakgerekbunubildirir.Yanielinizdebirdosyaolsun,dosyanınilk100byte'ını20.byte'tanitibarenokumanızgerekirsekullanacağınızmethodbudur:)
#1byteatlayarak3byteokudukve
IO.binread("test.png",3,1)#=>"PNG"
binwrite
Tahminedeceğinizgibibinreadintersi,yaniBinaryolarakyazmaişiniyapanmethod.Aynışekildeopsiyonel2ve3.parametrelerikullanabilirsiniz.
copystream
Birebirkopyayapmayayarar.İlkparametreSOURCEyanineyikopyalacaksınız,ikinciparametreDESTINATIONyaninereyekopyalacaksınız,eğerkullanırsanız3.parametrekopyalanacakbyteadedi,eğer4.parametrekullanırsanızaynıread/writedakigibioffsetdeğeriolarakkullanabilirsiniz.
FileSystemveIO(DosyaSistemi)
152
foreach
Elimizdetest-file.txtolsunveiçinde;
satır1
satır2
yazsın...Satır-satıriçindedolaşmakiçin;
IO.foreach("test-file.txt"){|x|print"busatır:",x}
Dediğimizdeçıktı;
busatır:satır1
busatır:satır2
şeklindeiçeriyeblockpasedipkullanabiliriz.
popen
Subprocessyanialtişlemleraçmakiçinkullanılır.ÖzellikleRubyüzerindenSHELLkomutlarıçağırmakiçinçokkullanılanbiryöntemdir.Asenkronişler.
#Buişlemasenkron/altişlemolarakçalışır...
IO.popen("date")do|response|
system_date=response.gets
puts"system_date:#{system_date}"
end
/tmp/dizininilisteleyelim:
p=IO.popen("ls/tmp/")
p.pid#=>52389
p.readlines#=>["D8D75028-234B-4F49-9358-C4C4775B4A08_IN\n","D8D75028-234B-4F49-935
8-C4C4775B4A08_OUT\n","F7C71944B49B446081C0603DE90E4855_IN\n","F7C71944B49B446081C06
03DE90E4855_OUT\n","KSOutOfProcessFetcher.501.OlaJUhhgKAnFsX7fZ0FyXTFxIgg=\n","com.a
pple.launchd.4H4RVax25p\n","com.apple.launchd.Kn8Wcx4NQX\n","fo\n","lilo.12159\n",
"swtag.log\n","test-file.txt\n"]
GördüğünüzgibipidyaniProcessID:52389,eğershell'den;
psax|grep52389
derseniz;
52389??Z0:00.00(ls)
FileSystemveIO(DosyaSistemi)
153
gibiilgiliişlemigörürsünüz.
FileSystemveIO(DosyaSistemi)
154
ExceptionHandling
ExceptionHandling
155
KernelModülü
KernelModülü
156
Bölüm6Bubölümde;
MonkeyPatchingRegularExpressionsTimeveDateNesneleriRubyPaketleri:RubyGemsPaketYöneticisi:BundlerKomutSatırı(Command-Line)KullanımıMetaProgramming
konularınıişleyeceğiz
Bölüm6
157
MonkeyPatchingRuby'ninenşaibeliözelliklerindenbiridir.Kimileriiçinmüthişbirşeykimileriiçindeçoktehlikelibirözelliktir.7.7'debahsettiğimMetaProgrammingkonusuiledeçokyakındanalakalıdır.
Ruby'dekitümsınıflaraçıktır.YaniKernel'dangelenherhangibirsınıfımodifiyeetmekmümkündür.Budurumyanlışellerdeçoktehlikeliolabilir.
Yani,Stringsınıfındakiherhangibirmethod'ubozmakmümkündür.Örneğin,String#lengthmethodunudeğiştirelim:
"Hello".length#=>5#Bunormali
#MonkeyPatchingyapıyoruzvelengthmethod'unudeğiştiriyoruz.
classString
deflength
"Uzunluk:#{self.size}karakterdir."
end
end
"Hello".length#=>"Uzunluk:5karakterdir."
NormalşartlaraltındalengthmethoduFixnumdönmesigerekirken,bozduğumuzmethodbizeStringdöndü.Anlatabilmekiçinbudenliabartıbirörnekvermekistedim.Düşünsenize,kullandığınızherhangibirkütüphane,kafasınagöre,standartolanherhangibirmethod'ubuşekildebozsa?
Tümkodunuzçorbayadönerveiçindençıkamazbirhalegelir.Pekiasılkullanımamacıbumudur?Tabiikideğil.Bizekolaylıksağlayanişlerdekullanmamızgerekiyor.
Örneğin,basitbirmatematikişlemiiçin,5kere5önermesinikullanmakistiyoruz:
classFixnum
defkere(n)
self*n
end
end
Fixnumiçinekerediyebirmethodtaktık.Haydikullanalım:
5.kere(5)#=>25
5.kere(5).kere(2)#=>50
MonkeyPatching
158
İştebutürbirMonkeyPatchingişeyararvekullanılabilitesiyüksekolanbiryöntemdir.KezaRubyonRailswebframework'üneredeysebumantıküzerinekurulmuştur.
Örneğin5günönceşeklindebirönermeyapmakistiyoruz.
classFixnum
defgün
self*24*60*60
end
defönce
Time.now-self
end
defsonra
Time.now+self
end
end
Şimdişöylebirşeyyapalım:
Time.now#=>2015-02-0912:55:33+0200
5.gün.önce#=>2015-02-0412:55:33+0200
1.gün.sonra#=>2015-02-1012:55:33+0200
Fixnumyanibasitsayılara.gün.önceve.gün.sonragibiikitanemethodekledik:)
MonkeyPatching
159
RegularExpressionswip...
RegularExpressions
160
TimeveDateNesneleriZaman,tarihvesaatgibiişlemleriyapmakiçinRubyilebirliktegelenTimeveDatesınıflarındanbahsedeceğim.Enbasittanımıylasaatinkaçolduğunuyadanowyanişimdi/şuandayıbulmakiçin:
Time
Time.now#=>2015-04-2808:49:20+0300
yapmamızyeterlidir.Saniyebazındaeklemeyadaçıkartmayaparakbaşkazamanlarıdabulabiliriz.1saatönceyibulmakiçin60saniye*60dakikayapmamızyeterli.
Time.now-(60*60)#=>2015-04-2807:51:01+0300
HemenRuby'selbirhareketleufakbirşeyyapalım:
classFixnum
defseconds
self
end
defminutes
self*60
end
defhours
self*60*60
end
defdays
self*60*60*24
end
end
#10günsonrayıbulalım
Time.now+10.days#=>2015-05-0808:54:02+0300
SaatfarklarıyüzündençeşitliTimeZone'larmevcut.Anitibariyle(28Nisan2015)yerelzamanabaktığımda:
Time.local(2015,4,28,8,54)#=>2015-04-2808:54:00+0300
PekiGMT'yegöredurumne?
TimeveDateNesneleri
161
Time.gm(2015,4,28,8,54)#=>2015-04-2808:54:00UTC
Şimdikendiistediğimizbirzamanıoluşturalım.Doğduğumyılveayıkullanarakbirzamanoluşturupkabacahangigünedenkgeldiğinibulalım.SadeceYILveAYkullanıyoruz!
t=Time.new(1972,8)#=>1972-08-0100:00:00+0300
t.monday?#=>false
t.tuesday?#=>true
Rubybizeotomatikolarakayınbiriniişaretettive1Ağustos1972'ninsalıgününedenkgeldiğinituesday?method'uileanladık.
Tahminedebileceğinizgibi,İngilizceolarak,günlerikontroledebiliyoruz.Yanisunday?,monday?...gibi
EğerUNIX'inepochzamanformatındaistersek,yapmamızgerekento_imethod'uileinteger'açevirmek:
Time.new(1972,8).to_i#=>81464400
Eğerelimizdeepochcinsindenbirzamanvarsa:
Time.at(81464400)#=>1972-08-0100:00:00+0300
Time.at(81464400).year#=>1972
şeklindedekullanabiliriz.Bunlaraekolarak;
Time.now.zone#=>"EEST"
Time.now.day#=>29
Time.now.wday#=>3#çarşamba
Time.now.utc?#=>false
Time.now.gmt?#=>false
Zamanlararasındakifarkıbulmakiçindeaynımatematikişlemigibiyaparmışgibidavranabilirsiniz.
birth_day=Time.new(1972,8)#Ağustos1972
Time.now.to_i#=>1430284388
birth_day.to_i#=>81464400
Time.now.to_i-birth_day.to_i#=>1348819988saniye
1348819870/(60*60*24)#=>15611gün
1348819870/(60*60*24*30)#=>520ay
1348819870/(60*60*24*30*12)#=>43yıl
TimeveDateNesneleri
162
Aynişekildekarşılaştırmaişlemleridematematikişlemlerigibi.Doğduğumyılilebugünükarşılaştıralım:
birth_day=Time.new(1972,8)
now=Time.now
tomorrow=now+(60*60*24)
now.to_i#=>1430284645
tomorrow.to_i#=>1430371045
birth_day.to_i#=>81464400
now.to_i>birth_day.to_i#=>truebugün>doğumtarihi
now.to_i>tomorrow.to_i#=>falsebugün<yarın
tomorrow.to_i>now.to_i#=>trueyarın>bugün
ZamanıFormatlıŞekildeGöstermekTarihbilgisiniistediğimizşekildeformatederekçıktıalabiliriz.
t=Time.now
t.strftime("Bugün%d%B%Y,%A,saat:%H:%M")#=>"Bugün01May2015,Friday,saat:1
2:35"
Dikkatettiysenizİngilizceolarakçıktıyıaldık.NeyazıkkiRuby'delocalekavramıyok.BuyüzdenTürkçeçıktıalmakiçinI18ngem'inikullanmamızgerekiyor.
geminstalli18n
Dahasonraherhangibirdizinaltında;
cd~
mkdiri18n-works
cdi18n-works/
mkdirlocales
cdlocales/
curl-Ohttps://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/tr.
yml
cd../..
touchrun.rb
şimdirun.rbdosyasıiçine;
TimeveDateNesneleri
163
require'i18n'
I18n.load_path=Dir['./locales/*.yml']
I18n.locale=:tr
putsI18n.locale
t=Time.now
putsI18n.localizet,:format=>"Bugün%d%B%Y,%A,saat:%H:%M"
yaptığımızdaçıktı:
tr
Bugün01Mayıs2015,Cuma,saat:12:55
şeklindeolacaktır.
Kullanımda:%<flags><width><modifier><conversion>şeklindebiryöntembulunmakta.
Flag'ler
-don'tpadanumericaloutput
_usespacesforpadding
0usezerosforpadding
^upcasetheresultstring
#changecase
:usecolonsfor%z
Hemenörneklerlegörelim,ilkolarak-,_ve0kullanımınabakalım:
t=Time.now#=>2015-05-0211:35:26+0300
t.strftime("%d")#=>"02"
#şimdi-ileyapıyoruz
t.strftime("%-d")#=>"2"#0'ladoldurmadı...
#şimdi_ileyapıyoruz
t.strftime("%_d")#=>"2"#SPACEkarakteriiledoldurdu...
#şimdi0ileyapıyoruz
t.strftime("%0d")#=>"02"#0iledoldurdu...
Şimdi ̂ ,#ve:flag'lerinebakalım:
t.strftime("%A")#=>"Saturday"
t.strftime("%^A")#=>"SATURDAY"#upcaseyaptı
t.strftime("%#A")#=>"SATURDAY"#changecasedemek,upcaseisedown,downcase
iseupyapmakdemek.
#saturdaydowncasegeldi,upcaseoldu
t.strftime("%z")#=>"+0300"
t.strftime("%:z")#=>"+03:00"#:ileayırdı
TimeveDateNesneleri
164
width
t.strftime("%d")#=>"02"
t.strftime("%10d")#=>"0000000002"#10basamakyaptı.
Formatlama
İşaret Açıklama
%Y 4dijitliyıl
%C yıl/100,yüzyıliçin
%y yılmod100,2015için15gelir.
%m Yılınayı.(01..12)
%B Ayıntamadı(January)
%byada%h Ayınkısaadı(Jan)
%d Ayıngünü,0eklemeli(01..31)
%e Ayıngünü,SPACEkarakterieklemeli(1..31)
%j Yılıngünü(001..366)
%H Saat,24-saatformatında0eklemeli(00..23)
%k Saat,24-saatformatındaSPACEkarakterieklemeli(0..23)
%I Saat,12-saatformatında0eklemeli(01..12)
%l Saat,12-saatformatındaSPACEkarakterieklemeli(1..12)
%P Meridyengöstergeci,küçükharf(amyadapm)
%p Meridyengöstergeci,büyükharf(AMyadaPM)
%M Dakika(00..59)
%S Saniye(00..60)
%L Milisaniye(000..999)
%N Kesirlisaniye,varsayılan9dijitli
%z saatvedakikaofsetliUTCzamankuşağı(timezone)
%Z Zamankuşağınınharfselkarşılığı
%A Haftanıngünü,tamyazım
%a Haftanıngünü,kısayazım
%u Haftanınkaçıncıgünü,Pazartesi1
%w Haftanınkaçıncıgünü,Pazar0
%c "%a%b%e%T%Y"şeklinde
%D "%m/%d/%y"şeklinde
TimeveDateNesneleri
165
%F ISO8601-"%Y-%m-%d"
%v VMS-"%e-%^b-%4Y"
%x %Dileaynı
%X %Tileaynı
%r 12saatcinsindensaat"%I:%M:%S%p"
%R 24saatcinsindensaat"%H:%M"
%T 23saatcinsindensaat"%H:%M:%S"
Örnek
t=Time.now#=>2015-05-1614:29:43+0300
t.strftime("%N")#=>"691659000"
t.strftime("%3N")#=>"691"#milisaniye,3dijit
t.strftime("%6N")#=>"691659"#mikrosaniye,6dijit
t.strftime("%z")#=>"+0300"
t.strftime("%Z")#=>"EEST"
#EasternEuropeanSummerTimeyani
#yazsaati:)
t.strftime("%A")#Sunday
t.strftime("%a")#Sun
t.strftime("%u")#"7"
t.strftime("%w")#"0"
@wip
TimeveDateNesneleri
166
Rubypaketleri:RubyGemsRuby,benzeridiğerdillerdekigibikendineaitbirpaketyöneticisinesahiptir.RubypaketlerineGemdenir.Gem'leraslındatekrartekrarkullanılabilecekRubykodlarınınpaketlenmişhalleridirveherhangibirRubyuygulamasınaçokkolayentegreedilebilir.
Geneldetümpaketlerhttp://rubygems.orgsitesindesunulur.İsterlocal(yerel)isterözelrepositoryistersenizdeRubyGemssitesindenbupaketlerikurabilirsiniz.
Rubykurulumundagemadındabirkomuteklenirsisteme.Eğergem--helpderseniz,ilgilikullanımlarıvekomutlarılisteleyebilirsiniz.
RubyGems,efsaneisimJimWeirichtarafındanyazılmıştı.Kendisi2014Şubat'taaramızdanayrıldı.
HerhangibirpaketikurmakiçingeminstallPAKET_ADIşeklindeyazmakyeterlifakatgeneldeRuby'ninkuruluolduğuyersistemdosyalarınınkuruluolduğuyerdeolduğuiçineğerRubyversiyonyöneticisi(rvmyadarbenv)kullanmıyorsanızsudoileileişlemyapmanızgerekir:sudogeminstallPAKET_ADI.
TavsiyemRbenvyadaRVMgibibirpaketyöneticisikullanmanız.BirsonrakibölümdegöreceğimizBundleraracıylahemsisteminizigereksizgem'lerdenkorumuşolacağızhemdeistediğimizprojedeistediğimizgemversiyonunukullanmışolacağız.
RubyPaketleri:RubyGems
167
Paketyöneticisi:Bundlerwip...
PaketYöneticisi:Bundler
168
KomutSatırı(Command-Line)Kullanımıwip...
KomutSatırı(Command-Line)Kullanımı
169
MetaProgrammingRuby'dekiMetaProgramming,yazılankodunrun-time'dapekçokşeyideğiştirmesi,Kernel'dangelensistemfonksiyonlarınımanipuleetmesi(Class,Module,Instanceileilgilişeyler)şeklindedir.
Hattabazenyazdığınızprogramırestartetmedenbilekodudeğişikliğiyapmakmümkünolur.
Bazıkomutlar,kullanımşekillerigerçektendeçoktehlikeliolabilir!Özellikledışdünyadangelecekinput'larınrun-time'dayorumlanmasıpekdeönerilenbiryöntemdeğildir.Yaniburadagöreceğimizbazıyöntemleribilelimamagerçekdünyadapekfazlauygulamayalım!
Class'larDeğiştirilebilir!İsterKernelisterdışarıdaneklenen,hertürClassmodifiyeedilebilir:
classString
deffoo
"foo:#{self}"
end
end
a="hello"
a.foo#=>"foo:hello"
StringClass'ınakafamızagörefoomethod'uekledik.
Class'larınBirdenFazlainitializeYöntemiOlabilir!BuClassOverloadingyaniClassyadamethod'uezmekolarakdüşünülebilir.Class'ınbirtaneinitializemethod'uolduğuiçin,koşulluolarakClass'abaşlangıçseviyesindemüdahaleedebiliriz:
MetaProgramming
170
#Dortgen.new([sol_ust_x,sol_ust_y],boy,en)
#Dortgen.new([sol_ust_x,sol_ust_y],[sag_alt_x,sag_alt_y])
classDortgen
definitialize(*args)
ifargs.size<2||args.size>3
"Busınıfenaz2enfazla3parametrealır"
else
"Doğruparametrekullanımı"
end
end
end
Dortgen.new([0,0],10,10)#=>#<Dortgen:0x007fe3ea1330f0>
Dortgen.new([0,0],[10,10])#=>#<Dortgen:0x007fe3ea132d58>
İster2,ister3parametreileinitializeettiğimizDortgensınıfı,parametrekullanımınagörefarklıçıktılarüretebilir.
AnonimClassAnonimClass'lar,Singleton,GhostyadaMetaclassdiyedeadlandırılır.AslındaherRubyClass'ıkendineaitanonimbirsınıfavemethod'larasahiptir.Tekfarkıkendisineaitolmasıdır.
classDeveloper
class<<self
defpersonality
"Awesome"
end
end
end
Developer.new#=>#<Developer:0x007fc9048a2738>
Developer.personality#=>"Awesome"
a=Developer.new
a#=>#<Developer:0x007fc9048a2120>
a.class#=>Developer
a.class.personality#=>"Awesome"
a.personality#=>undefinedmethod`personality'for#<Developer:0x007fd3ca0a
0e10>(NoMethodError)
Developersınıfınınkendiclass'ınaanonimbirmethodtaktık.Class'daninstanceüretmedenDeveloper.personalityşeklindeerişebilirken,ainstance'ındangitmekistediğimizdeyania.personalitydediğimizdehatamesajıaldık.Oysaomethodssadecea.classaait:)
YaptığımızişaslındabirSingletonoluşturmaoldu.
define_method
MetaProgramming
171
Classiçinderun-timeyanidinamikolarakmethodoluşturabilirsiniz:
classDeveloper
define_method:personalitydo|arg|
"Youare#{arg}developer!"
end
end
Developer.new.personality("anawesome")#=>"Youareanawesomedeveloper!"
a=Developer.new
a.personality("anawesome")#=>"Youareanawesomedeveloper!"
a.class.instance_methods(false)#=>[:personality]
send
sendmethod'uObjectsınıfındangelenbirmethod'dur.Sınıfagöndereceğimizmesajilkparametreolupbudaaslındaçağıracağımızmethodadıdır.
classDeveloper
defhello(*args)
"Hello#{args.join("")}"
end
end
d=Developer.new
d.send(:hello,"vigo","howareyou?")#=>"Hellovigohowareyou?"
Unutmayın,sadecepublicmethod'laraerişebilirsiniz!
remove_methodveundef_method
Adındandaanlaşılacağıgibimethod'uyoketmekiçinkullanılıramaeğerremove_methodileiptaledilmekistenilenmethod,türediğiüstsınıfındavariseneyazıkkiyokedilemez.Budurumdadaundef_methoddevreyegirer:
MetaProgramming
172
classDeveloper
defmethod_missing(m,*args,&block)
"#{m}isnotavailable!"
end
defhello
"HellofromclassDeveloper"
end
end
classTurkishDeveloper<Developer
defhello
"HellofromclassTurkishDeveloper"
end
end
d=TurkishDeveloper.new
d.hello#=>"HellofromclassTurkishDeveloper"
classTurkishDeveloper
remove_method:hello
end
d.hello#=>"HellofromclassDeveloper"#üstsınıftavarolduğuiçinçalıştı!
Eğer;
classTurkishDeveloper
undef_method:hello
end
d.hello#=>"helloisnotavailable!"
yaparsak,methodkompleuçarvemethod_missingileyakaladığımızkodbloğuçalışır.
eval
Pekçokprogramlamadilindeevaluateetmektengelen,yaniStringformundakimetninçalışabilirkodparçasıhalinegelmesiolayıdıreval:
eval("5+5")#=>10
eval('"Hello".downcase')#=>"hello"
Aslındaçoktehlikelidir.Yaniprogramatikhiçbirkontrololmadandümdüzmetninexecutablehalegetirilmesidirvehiçbirzamanönerilmez.Güvenlikzafiyetidoğrurabilir.
instance_eval
YazılankodbloğunusankiClass'ınbirmethod'uymuşgibiçalıştırır:
MetaProgramming
173
classDeveloper
definitialize
@star=10
end
end
d=Developer.new
d.instance_evaldo
putsself
puts@star
end
##<Developer:0x007fe549a91e70>
#10
yada;
classDeveloper
end
Developer.instance_evaldo
defwho
"vigo"
end
end
Developer.who#=>"vigo"
şeklindekullanılır.Aynışekildesadecepublicolanmethod'lariçingeçerlidir.
module_evalveclass_eval
İkisideaynıişiyapar.DışarıdanClassdeğişkenlerineerişmekiçinkullanılır:
classDeveloper
@@geek_rate=10
end
Developer.class_eval("@@geek_rate")#=>10
Aynışekildemethodtanımlamakiçin;
classDeveloper
end
Developer.class_evaldo
defwho
"vigo"
end
end
Developer.new.who#=>"vigo"
class_variable_getveclass_variable_set
MetaProgramming
174
ClasskonusundaClassveInstanceVariablesarasındakifarkıgörmüştük.Buikimethodyardımıylasınıfdeğişkenineerişmekvedeğerinideğiştirmekmümkün:
classDeveloper
@@geek_rate=10
end
Developer.class_variable_set(:@@geek_rate,"100")#=>"100"
Developer.class_variable_get(:@@geek_rate)#=>"100"
instance_variable_getveinstance_variable_set
Aynıöncekigibi,bumethod'lardasadeceInstanceVariableiçinçalışır:
classDeveloper
definitialize(name,star)
@name=name
@star=star
end
defshow
"Name:#{@name},Star:#{@star}"
end
end
d=Developer.new("vigo",10)
d.instance_variable_get(:@name)#=>"vigo"
d.instance_variable_get(:@star)#=>10
d.show#=>"Name:vigo,Star:10"
d.instance_variable_set(:@name,"lego")#=>"lego"
d.show#=>"Name:lego,Star:10"
const_getveconst_set
ConstantyanisabitleriClassveModulekonusundagörmüştük.const_setileClass'asabitdeğeratıyoruz,const_getiledeilgilideğeriokuyoruz:
classBox
end
Box.const_set("NAME","web")#=>"web"
Box.const_get("NAME")#=>"web"
Box::NAME#=>"web"
a=Box.new
a.class.constants#=>[:NAME]
a.class::NAME#=>"web"
MetaProgramming
175
KodYazmaTarzı(StyleGuide)Aşağıdakikurallar,kodundoğruçalışmasındanziyade,kullanıcıtarafındandoğruokunupalgılanmasıiçindüşünülmüş,kabuledilmişkurallardır.
Ruby'eaitresmibirdurumolmasada,geneldetümkullanıcılarbukurallarauymayaçalışır.
BukurallarıbenGitHub'danaldım.
soft-tabsyaniTABkarakteriyerine2adetspacekarakteriilegirintiyapılmalıMümkünsesatıruzunluğu80karakterigeçmesin!Satırsonlarındaboşkarakterwhite-spacebırakmayın!HerrbdosyasıyadaRubykoduiçerendosyaboşbirsatırlabitsin.Operatörler,virgül,ikinokta,noktalıvirgül,{ve}lerinetrafındamutlakaboşlukspacekarakteriolsun!
Yanlış
a=1
a,b=1,3
1>2?true:false;puts"Merhaba"
[1,2,3].each{|n|putsn}
Doğru
a=1
a,b=1,3
1>2?true:false;puts"Merhaba"
[1,2,3].each{|n|putsn}
ParantezveKöşeliparantezkullanırken,neöncesinenedesonrasınaboşkarakterspacekoyma!
Doğru
my_method(arg1,arg2).other
[1,2,3].length
Ünlemdensonraboşkarakterspacekullanma!array.include?(element)whenvecasekullanırkengirintidurumunuaşağıdakigibiyap:
KodYazmaTarzı(StyleGuide)
176
case
whensong.name=="Misty"
puts"Notagain!"
whensong.duration>120
puts"Toolong!"
whenTime.now.hour>21
puts"It'stoolate"
else
song.play
end
kind=caseyear
when1850..1889then"Blues"
when1890..1909then"Ragtime"
when1910..1929then"NewOrleansJazz"
when1930..1939then"Swing"
when1940..1950then"Bebop"
else"Jazz"
end
Method'lararasında1satırboşlukver,gerekiyorsamantıklıbirşekildeiçerideayrımyap!
defsome_method
data=initialize(options)
data.manipulate!
data.result
end
defsome_method
result
end
SyntaxEğermethod'aparametregeçiyorsanparantezyaz!
defsome_method
#argümansız
end
defsome_method_with_arguments(arg1,arg2)
#argümanlı
end
forkullanımınadikkatedin,kafanızagöreheryerdekullanmayın:
KodYazmaTarzı(StyleGuide)
177
arr=[1,2,3]
#kötüörnek
foriinarrdo
putsi
end
#iyiörnek
arr.each{|i|putsi}
İçiçeternarykullanmaktankaçının!Okunabilirliğiazaltıyor!
#kötü
some_condition?(nested_condition?nested_something:nested_something_else):somet
hing_else
#iyi
ifsome_condition
nested_condition?nested_something:nested_something_else
else
something_else
end
andveoryerine&&ve||kullanınMümkünoldukçaifleriteksatırşeklindekullanın:
#kötü
ifsome_condition
do_something
end
#iyi
do_somethingifsome_condition
unlessiçindeelsekullanmaktankaçının:
#kötü
unlesssuccess?
puts"hata"
else
puts"ok"
end
#good
ifsuccess?
puts"ok"
else
puts"hata"
end
KodYazmaTarzı(StyleGuide)
178
Teksatırlıkblokişlerinde{},çoksatırlıkblokişlerindedoendkullanın.returnkelimesinigerekmedikçekullanmayın.Method'lardaparametreolarakdefaultdeğeratarken=etrafındaspacekullanın.
#kötü
defsome_method(arg1=:default,arg2=nil,arg3=[])
#kod...
end
#iyi
defsome_method(arg1=:default,arg2=nil,arg3=[])
#kod...
end
Varlıkoperatörükullanmaktançekinmeyin!
#eğerisimnilyadafalseiseisimdeğişkenine"vigo"ata
isim||="vigo"
Booleandeğerleriçin||=kullanmayın!
#kötü
enabled||=true
#iyi
enabled=trueifenabled.nil?
Parantezlikullanımdamethod'dansonraspacekullanmayın:
#kötü
f(3+2)+1
#iyi
f(3+2)+1
Blockiçindekullanmayacağınızdeğişkeniçindeğeratamasıyapmayın:
#kötü,kboşagitti
result=hash.map{|k,v|v+1}
#iyi
result=hash.map{|_,v|v+1}
Veritipikontrolüiçin===kullanmayın!is_ayadakind_of?kullanın.
Naming(İsimlendirmeler)
KodYazmaTarzı(StyleGuide)
179
Methodvedeğişkenisimleriiçinsnake_casekullanın.ClassveModüliçinCamelCasekullanın.ConstantiçinSCREAMING_SNAKE_CASEkullanın.Booleansonuçdönenmethod'lar?ilebitmeli:User.is_valid?Tehlike,nesneyimodifiyeeden/değiştirenmethod'lar!ilebitmeli!User.delete!
ClassSingletontanımlarkenselfkullanın:
classTestClass
#kötü
defTestClass.some_method
#kod
end
#iyi
defself.some_other_method
#kod
end
end
private,public,protectedolanmethod'lardagirintilememethodadıylaaynıhizadaolsunveilgilimethod'unbirüstsatırıboşkalsın:
classSomeClass
defpublic_method
#...
end
private
defprivate_method
#...
end
end
ExceptionsAkışkontolüiçinkullanmayın!
KodYazmaTarzı(StyleGuide)
180
#kötü
begin
n/d
rescueZeroDivisionError
puts"0'abölünmehatası!"
end
#iyi
ifd.zero?
puts"0'abölünmehatası!"
else
n/d
end
DiğerString'lericoncatederkeninterpolasyonkullanın:
#kötü
email_with_name=user.name+"<"+user.email+">"
#iyi
email_with_name="#{user.name}<#{user.email}>"
Gerekmedikçedeğeratamalarındatektırnak'kullanmayın,çifttırnağıtercihedin"StringconcatişlerindeArray'eeklemetekniğinikullanabilirsiniz,hızlıdaolur:
html=""
html<<"<h1>Pagetitle</h1>"
paragraphs.eachdo|paragraph|
html<<"<p>#{paragraph}</p>"
end
KodYazmaTarzı(StyleGuide)
181
GerçekHayatRubyÖrnekleriBubölümde,gerçekdünyadakiRubykonularınadeğineceğim.BunlarınbaşındadaNedenRuby?sorusunacevapvermeyeçalışacağım.BenceRubydünyasınıöneçıkartanenbüyükfarklılıkTestDrivenDevelopmentmetodolojisininçokgelişmişolması.
Onlarcatestkütüphanesi,testsuitevebenzerişeylerbencediğerdillerdebukadarileriseviyededeğil.YaptığınızuygulamayıENDTOENDyaniA'danZ'yetestetmek,tektektümsenaryolarıçıkartmakveneredeysesıfırhataileişyapmakmümkün.
BehaviourDrivenDevelopment(BDD),ContinuesIntegration(CI),testvebuildotomasyonudaçoksıkkullanacağımızşeylerdenbiri!
Genelanlamdakonubaşlıklarımız;
NedenRuby?RubyveTDD/BDD/CIKendiRubygem'imiziyapalım!SinatraveWeb
GerçekHayatRubyÖrnekleri
182
NedenRuby?YazılımhayatımaCommodore16BASICdiliilebaşladım.DahasonraCommodore64'egeçtim,Assembly(MakineDili),dahasonradaAmiga'dadaAssembly'yedevamettim.Birgüngeldivemakinediliçöpoldu:)Teknolojideğişti:)
90'lıyıllardaWindowsveASPdiliyletanıştım.ASP'ninilkgünleri,VBScript:)UzuncabirsüreASPileyoladevamettiktensonraPHPiletanıştımve"ooohbeDÜNYAvarmış"dedim.
PHPilehatırısayılırpekçokprojeyaptım.Dahasonra,sevgilikardeşimFıratCanBaşarır'ınyönlendirmesiylePython)veDjango)iletanıştım.Özelliklewebdevelopmentişleriyleuğraşanbiri,PHP'densonraPythonveDjango'yugörüncehakikattenaklıduruyor!
ÖzellikleDjangoilebirliktegelenAdminPanelolayıinsanıntabiricaizsedibinidüşürüyor!Dahasonraanlaşılıyorki,bupanel,sadecedeveloperiçin.Yanisadecegeliştirmeamaçlı.İlkanda"ooof,bununlahemenhızlıcaişleriçıkartırım"diyorsunuzhaklıolarak.Teoridemümkünde.
AncakbüyükbirişekalkıştığınızdabuAdminPanelkabusunuzoluyorveişigücübırakıpsadecebupanelicustomize(yaniözelleştirme)etmekleuğraşıyorsunuz.
KezaPython2mi?3mü?gibidurumlardasözkonusu.Python3neredeysetamamenfarklı.Anitibariyle(30Kasım2014)halenDjangovePython3desteğiresmiolarakgelmişdeğil.
BunundışındaPythontopluluğuçokağırhareketediyor.Yeniçıkanbirservisinmodülolarakhazırlanmasıyadaenson3seneöncegüncellenmiş,yüzlercepull-request'inbeklediğiGitHubprojelerimiistersiniz?
Bukonularbenigeliştiriciolarakzorladı.Amacımhızlaişimidüzgünbirşekildeyapıpyolumadevametmektenbaşkabirşeydeğil.
RubyisFun!YaniRubyeğlencelidir!nedemekbu?İlkbakıştainsandüşünüyor,programlamadilininneresieğlenceliolabilirki?Neticedebilimselbirişlemdiyedüşünüyorinsan.TaakiRubyileuğraşmayabaşlayanakadar...
İlkdikkatçekenşey,Rubydilinininsandilineçokbenzemesi.Yaniİngilizcebilenbiriiçinokunmasıçokkolay.HiçRubybilmeyenbiribilerahatlıklanetürbirişlemolduğunuanlayabilir.
Dahaöncehiçbirprogramlamadilinderastlamadığımbirifkullanımı:
puts"vigo"ifa>2
NedenRuby?
183
Buşudemek,eğera'nındeğeri2'denbüyükseekranavigoyaz.Asp,Python,Php,Perl,CgibidillerdegeneldeifbloğuiçindeyadaonelineyaniteksatırdaifadeşeklindeolurkenilkkezRuby'deifkoşulununbuşekildekullanıldığınıgördüm.
unlesskelimeanlamıolarakifnotanlamındadır.Yanieğerx'indeğerifalseiseşunuyapderken:
puts"vigo"unlessx
gibibirkullanımsözkonusu.yaniaşağıdakigibidekullanılabiliramamantıksalolaraktercihedilmez:
puts"vigo"if!x
Kezamethodisimleri,standartkütüphaneilegelenözelliklergayetakıldakalıcıvemantıklı.Rubysizinadınızapekçokşeyidüşünüphazırkullanımasunuyor.
Acababugüngünlerdencumamı?
Hemenbakalım:
Time.now.friday?#=>true#evet
Aslındaçokbasitamaçokişeyarayanbirözellik.ButarzkonularaSyntacticSugardeniliyor.
ÇokGüçlüveÇalışkanRubyTopluluğuNeyazıkkiülkemizdeçokdabilinenyadatercihedilenbirdilolmamasınarağmen,dünyadadurumçokfarklı.PekçoktanıdıkprojeRuby,RubyonRails,SinatragibiRubydünyasınınaraçlarınıkullanmakta.
Python'dangelenbirgeliştiriciolarak,yaşadığımenbüyüksıkıntılardanbirideyavaşilerlemedurumuydu.Python'ubenAlmanMühendisliğinebenzetiyorum.Herşeyinanılmazkurallı,süpersistemliolmakzorunda.Tamambuçokgüzelbiryaklaşım,kabulediyorumamabazenağırkalıyor.
BazenöylebirPythonmodülüneihtiyacınızoluyorvebirbakıyorsunuzson3yıldırgüncellemeyapılmamış,GitHub'dabekleyen50tanePullRequest,kodukiminmaintainettiğibellideğil,uzayboşluğundakendikendinegidenbirdurumdakaderinibekliyor.
Rubytopluluğuinanılmazderecedeüretken.YenibirAPI'mıçıktı?Hemengem'inibulmanızmümkün!Rubymiöğrenmekistiyorsunuz?Tonlarcaücretsiz/ücretlionlinevideolar,eğitimlervar!Kitap,kod,konferansaklınızanegelirse...
NedenRuby?
184
Neyazıkkibudenliaktifbirdünyayıbendiğeruğraştığımdillerdegöremedim.
Birişiyapmanınpekçokfarklıyoluolabilir!Sonolarak,Ruby'dekiençokhoşumagidenmentalitedenbahsetmekistiyorum.Birişidoğruyapmanınbirdenfazlayoluolabilir.
ÖrneğinPython'dasadece"tekbiryol"varkenRuby'defarklıfarklıyöntemlerle,komutlarlaaynıişideğişikşekillerdeyapabilirsinizvehepsidedoğrudur!
NeredeysehiçbirprogramlamadiliDSL(yaniDomainSpecificLanguage)yapmakiçinbudenlimüsaitdeğil.YaniRubykullanarakkafanızagöreRubyüzerindeçalışanbaşkabirdünyayapabilirsiniz!
Neticedehayattaherşeytercihlervezevklerleilgilidir.Benkendinedenlerimibelirtiyorum,bunlarsizeuymayabilir,hattanefretbileedebilirsiniz.Eğerböylebirdurumvarsa,sizdenricamsakinbirşekildeRubydünyasınıincelemeniz.
AnitibariyleneileuğraşıyorsanızaynışeyiRubyileyapmayaçalışmanız.Mutlakadeneyin.Denedikten,tadınabaktıktansonrakararverin.
Sevgiliannemküçükkenhepderdi"öncebitadınabakondansonraistemiyorsanyemeğiyeme"diye:)
NedenRuby?
185
RubyveTDD/BDD/CIwip...
RubyveTDD/BDD/CI
186
KendiRubygem'imiziyapalım!wip...
KendiRubygem'imiziyapalım!
187
SinatraveWebBelkideenpopülerRubykütüphanesimicro-webframeworkSinatrailehızlıcaminiwebuygulamalarıyapmak,basitAPIservislerihazırlamakvesunucuyadeployetmekkonularınıişleyeceğiz!
wip...
SinatraveWeb
188
YazarHakkında1972’deİstanbul’dadoğdum.Rahmetlianne-annem’insatınaldığıCommodore16ilebilgisayarıhayatımıdeğiştirdi.UzunyıllarCommodore64veAmigakullandım.İnternetin,Google'ınveStackoverflow'unolmadığıbirdünyadaAssemblydiliilecodeyazdım.
1990'larınbaşında,televizyonlardafırtınagibiesenDinozorus,KüpKüp,SokakDövüşcüsügibioyunlarıAmigaplatformundakodlamıştım.1997'ninortalarınakadarAmigailedevamettimhayatıma.1998-2007arasındaWindows/PCkullanmakzorundakaldım.Asp3.0ilebaşlayanwebprogramlamamaceram,sırasıylaJavaScript,Php,Perl,PythonvesonolarakRubyiledevametmekte.
2003yılındaevlendim,2011’dedünyanınengüzelhediyesiniverdieşim.KızımEzeldünyayageldi!BazenberaberAmiga'daoyunoynuyoruz:)
UzunyıllarİstanbulBilgiÜniversitesi’ndeçalıştıktansonra2013’tewebBox.ioşirketinikurdum.Kod.io2013,Kod.io2014,Codefront.io,Jsist2014gibikonferanslardüzenledik.
Failconf,Hack-inggibiorganizasyonlarveçeşitlimeetup’laryaptık.Ocak2015’dewebBox.io’nunfaaliyetlerinibitirdik.Mayıs2015’tenberitekrareskigörevime,İstanbulBilgiÜniversitesi’negeridöndüm.
Halen,büyükbirheyecanla,AmigaveCommodore64makinediliprogramlamaileuğraşıyorum.Sizleredetavsiyeederim:)
YazarHakkında
189