107
Programowanie w języku Ruby Dr inż. Stanislaw Polak Grupa Systemów Komputerowych https://www.icsr.agh.edu.pl/~polak/ Dr inż. Stanislaw Polak 1 Materialy dla studentów Informatyki wydzialu IET AGH w Krakowie Plan wykladu I Język Ruby Zmienne Struktury kontrolne Typy danych Podprogramy Programowanie funkcyjne Obiektowość Obsluga WWW I Podstawowe pojęcia związane z tworzeniem aplikacji internetowych I Podstawy języka dziedzinowego „Sinatra” I Framework Ruby on Rails Wstęp Przyklad tworzenia aplikacji Kontroler Model Widok Lokalizacja i umiędzynarodowienie Uwierzytelnianie i autoryzacja Dr inż. Stanislaw Polak 2 Notatki Notatki

Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Programowanie w języku Ruby

Dr inż. Stanisław Polak

Grupa Systemów Komputerowych

https://www.icsr.agh.edu.pl/~polak/

Dr inż. Stanisław Polak 1

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wie

Plan wykładu

I Język RubyZmienneStruktury kontrolneTypy danychPodprogramyProgramowanie funkcyjneObiektowośćObsługa WWW

I Podstawowe pojęcia związane z tworzeniemaplikacji internetowych

I Podstawy języka dziedzinowego „Sinatra”I Framework Ruby on Rails

WstępPrzykład tworzenia aplikacjiKontrolerModelWidokLokalizacja i umiędzynarodowienieUwierzytelnianie i autoryzacja

Dr inż. Stanisław Polak 2

Notatki

Notatki

Page 2: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Organizacja przedmiotu

I Wykłady — co dwa tygodnie — przygotowaniedo danego ćwiczenia

I Ćwiczenia laboratoryjne — co dwa tygodnie,przez cały semestr

I Ocena końcowa obliczana na podstawie ilościpunktów za wykonanie:I Zestawu zadań programistycznych,

przeznaczonych do wykonania na zajęciachI Zestawu zadań domowych — termin oddania:

następne zajęcia

I Strona przedmiotu: https://www.icsr.agh.edu.pl/~polak/jezyki/ruby/

I Strona ćwiczeń laboratoryjnych:https://polak.icsr.agh.edu.pl/

Plan wykładówI Język RubyI Framework „Ruby on Rails”

Plan ćwiczeń

1. Składnia języka Ruby – typizacja

2. Przetwarzanie tekstu, wyrażenia regularne

3. Programowanie funkcyjne, obiektowość, TDD,programy ’gem’ oraz ’rake’

4. Interfejs Rack, podstawy języka dziedzinowego„Sinatra”

5. Framework „Ruby on Rails” — Kontroler oraztesty funkcjonalne

6. Framework „Ruby on Rails” — Model oraztesty jednostkowe

7. Framework „Ruby on Rails” — Widok oraztesty integracyjne

Dr inż. Stanisław Polak 3

Język Ruby Skrypty

Dr inż. Stanisław Polak 6

Notatki

Notatki

Page 3: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

esectionWstęp

Uruchamianie kodu / skryptu Ruby

1 #!/ usr/bin/env ruby2 print "Hello World\n"

hello.rb

1 $ ruby -e ’print "hello world\n"’2 hello world3 $ ruby4 print "Hello World\n"5 Ctrl+D6 Hello World7 $ irb8 2.5.0 :001 > print "Hello World\n"9 Hello World

10 => nil11 2.5.0 :002 > exit12 $ ruby hello.rb13 Hello World14 $ chmod 755 hello.rb15 $ ./ hello.rb16 Hello World

Terminal Linux / macOS

Dr inż. Stanisław Polak 6

Język Ruby Skrypty

Konwencje nazewnicze dla funkcji / metod

I number.even?()

I string.upcase!()

I car.brand=(’Fiat’)

I array.size()

Dr inż. Stanisław Polak 8

Notatki

Notatki

Page 4: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

Komentowanie kodu

Komentarze

1 # Ten cały wiersz jest komentarzem2 a = "#łańcuch znakowy" #Tu jest komentarz3 a = /#wyrażenie regularne/ #A tu kolejny komentarz4 #5 # Komentarz6 # Ciąg dalszy komentarza7 #

Osadzane bloki dokumentacji

1 =begin2 = NAZWA3 Przykładowy dokument RD45 = OPIS6 ...7 =end89 =begin html

10 <img src="Przyklad.png" alt="Rysunek 1." />11 <p>12 Oto kilka osadzonych HTML. W tym bloku mogę13 dołączać obrazy , użyć <span style="color: green">14 style </span > lub cokolwiek innego , co można zapisa

ć15 w HTML. Procesory RD, które nie wyprowadzają HTML ,16 będą to całkowicie ignorować.17 </p>18 =end19 if a > 220 print "a jest większe od 2\n"21 =begin2223 print "Ala ma kota\n"2425 =end26 b = 227 end28

Dr inż. Stanisław Polak 9

Język Ruby Skrypty

Wypisywanie danych

1 # ’to_s ’ is generally intended to return a human -readable representation of the object ,suitable for end users.

2 #’inspect ’, on the other hand , is intended fordebugging use , and should return arepresentation that is helpful to Rubydevelopers . The default ’inspect ’ method ,inherited from ’Object ’, simply calls ’to_s ’.

3 #Źródło: David Flanagan , Yukihiro Matsumoto , "TheRuby Programming Language"

4 ## #######################5 print(1.23, [4,5.67] , "8\ tdziewięć\n")6 puts7 printf("%e %s %s\n" ,1.23, [4 ,5.67], "8\ tdziewięć")8 puts9 puts(1.23, [4,5.67] , "8\ tdziewięć\n")

10 puts11 p(1.23 , [4,5.67], "8\ tdziewięć\n")12 puts13 p([{ pozycje: ["pomidor", "banan", "mango"],

sumarycznie: 200 }, { opcje_wysylki: ["dwa dni", "jeden dzień"]}, { metoda_platnosci: ["Gotówka", "Karta kredytowa"]}])

14 puts15 require "pp" #Ta linia jest wymagana dla wersji Ruby

< 2.5.016 pp(1.23, [4,5.67], "8\ tdziewięć\n")17 puts18 pp([{ pozycje: ["pomidor", "banan", "mango"],

sumarycznie: 200 }, { opcje_wysylki: ["dwa dni", "jeden dzień"]}, { metoda_platnosci: ["Gotówka", "Karta kredytowa"]}])

1 $ irb2 2.5.0 :001 > puts 1233 1234 => nil5 2.5.0 :002 > p 1236 1237 => 1238 2.5.0 :003 > pp 1239 123

10 => 12311 2.5.0 :004 > puts (123) ? true : false12 12313 => false14 2.5.0 :005 > p(123) ? true : false15 12316 => true17 2.5.0 :006 > pp(123) ? true : false18 12319 => true

Dr inż. Stanisław Polak 10

Notatki

Notatki

Page 5: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

Wczytywanie danychWczytanie pojedynczej wartości

1 require ’scanf’2 puts "Podaj dwie liczby"3 a,b = scanf("%d%f")4 printf("a=%d b=%f\n",a,b)5 ## ############################6 puts "Podaj znak"7 znak = STDIN.getc # lub znak = $stdin.getc8 printf("znak=%c\n",znak)

Na wyjściu (konsola)

Podaj dwie liczby123 4.56a=123 b=4.560000

Podaj znakaznak=a

Dr inż. Stanisław Polak 11

Język Ruby Skrypty

Wczytywanie danychWczytanie pojedynczej linii tekstu

1 puts ’######################### ’2 puts "Wprowadź dane:"3 dane = gets()4 # lub5 # dane = readline()6 puts ’######################### ’7 puts "Wprowadzone dane:"8 print dane9 puts ’-------------------------’

10 p dane11 puts ’######################### ’

Na wyjściu#########################Wprowadź dane:Ala ma kota i psa#########################Wprowadzone dane:Ala ma kota i psa-------------------------"Ala\tma kota i\tpsa\n"#########################

Na wyjściu#########################Wprowadź dane:Ctrl+D#########################Wprowadzone dane:

-------------------------nil#########################

Dr inż. Stanisław Polak 12

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 6: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

Wczytywanie danychWczytanie wielu linii tekstu

1 puts ’############# ’2 puts "Wprowadź dane:"3 while(dane = gets())4 puts ’############# ’5 puts "Wprowadzone dane:"6 puts dane7 puts ’-------------’8 p dane9 puts ’############# ’

10 puts "Wprowadź dane:"11 end

Na wyjściu#############Wprowadź dane:Ala#############Wprowadzone dane:Ala-------------"Ala\n"#############Wprowadź dane:ma kota i psa#############Wprowadzone dane:ma kota i psa-------------"ma kota i\tpsa\n"#############Wprowadź dane:Ctrl+D

1 puts ’############# ’2 puts "Wprowadź dane:"3 dane1 = STDIN.read()4 dane2 = readlines()5 puts ’############# ’6 puts "Wprowadzone dane:"7 puts dane18 puts dane29 puts ’-------------’

10 p dane111 p dane212 puts ’############# ’

Na wyjściu#############Wprowadź dane:Alama kota i psaCtrl+DAlama kota i psaCtrl+D#############Wprowadzone dane:Alama kota i psaAlama kota i psaCtrl+D-------------"Ala\nma kota i\tpsa\n"["Ala\n", "ma kota i \tpsa\n"]#############

Dr inż. Stanisław Polak 13

Język Ruby Skrypty

Umieszczanie danych w skrypcie

1 puts DATA.read2 END3 puts "Ten kod nie zostanie wykonany"4 Linia 25 Linia 3

Na wyjściu

puts "Ten kod nie zostanie wykonany"Linia 2Linia 3

Dr inż. Stanisław Polak 14

Notatki

Notatki

Page 7: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

Umieszczanie danych w skrypciePrzykład zastosowania

1 #!/ usr/bin/env ruby2 require ’rdoc’3 if ARGV [0] == ’--man’4 manual = DATA.read5 # html = RDoc :: Markup :: ToHtml.new(RDoc :: Options.new)6 ansi = RDoc:: Markup :: ToAnsi.new7 puts ansi.convert(manual)8 end9 __END__

10 = Name1112 pmh -convert.rb - converts an OAI -PMH document into the DOAJ

format; optionally also into the DBLP or PBN.1314 = SYNOPSIS1516 pmh -convert.rb [--help] [--man] [--version] [--doajLogin

username] [--doajPass password] [startDate] [endDate]1718 == Examples1920 * +pmh -convert.rb+ Generate , in the current directory , DOAJ

file for the entire period of time , i.e., for all (input) records

2122 * <tt>pmh -convert.rb 2013 -01 -01 2013 -07-30</tt> Generate , in

the current directory , DOAJ file for a given period oftime.

2324 Author :: Stanisław Polak (mailto:[email protected])

pmh-convert.rb

Rysunek: Wyświetlanie podręcznika użytkownika zpoziomu konsoli systemowej

Dr inż. Stanisław Polak 15

Język Ruby Skrypty

Bloki BEGIN oraz END

1 puts "Kod skryptu"2 END {3 puts "Ten również"4 }5 END {6 puts "Ten kod jest wykonywany tuż po zakończeniu wykonywania

kodu skryptu"7 }8 BEGIN {9 puts "Ten kod jest wykonywany tuż przed rozpoczęciem

wykonywania kodu skryptu"10 }11 BEGIN {12 puts "Ten też"13 }

Na wyjściuTen kod jest wykonywany tuż przed rozpoczęciemwykonywania kodu skryptuTen teżKod skryptuTen kod jest wykonywany tuż po zakończeniu wykonywaniakodu skryptuTen również

1 # Obliczanie sumy liczb wczytanych z klawiatury , aż do naciśnięcia Ctrl+D2 # -n 7→ while($_ = gets) do3 # #treść skryptu4 # end5 # -p 7→ while($_ = gets) do6 # #treść skryptu7 # puts $_8 # end9 $ ruby -ne ’suma += $_.to_i; BEGIN { suma = 0 }; END { puts suma }’

10 1 #$_ = "1\n"11 2 #$_ = "2\n"12 10 #$_ = "10\n"13 Ctrl+D14 13

Przykład użycia w jednolinijkowcu

Dr inż. Stanisław Polak 16

Notatki

Notatki

Page 8: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Skrypty

Ładowanie skryptu

1 if FILE == $PROGRAM NAME2 #Zmienna ’__FILE__ ’ ma wartość "skrypt.rb"3 #Zmienna ’$PROGRAM_NAME ’ ma wartość "skrypt.rb"4 puts "Ten skrypt został uruchomiony z linii komend

"5 else6 #Zmienna ’__FILE__ ’ ma wartość "skrypt.rb"7 #Zmienna ’$PROGRAM_NAME ’ ma wartość "irb"8 puts "Ten skrypt został załadowany z poziomu

innego skryptu"9 end

skrypt.rb

1 $ irb2 2.5.0 :001 > load ’./ skrypt.rb’3 Ten skrypt został załadowany z poziomu innego

skryptu4 => true5 2.5.0 :002 > load ’./ skrypt.rb’6 Ten skrypt został załadowany z poziomu innego

skryptu7 => true8 2.5.0 :003 > require ’./ skrypt ’9 Ten skrypt został załadowany z poziomu innego

skryptu10 => true11 2.5.0 :004 > require ’./ skrypt ’12 => false13 # $ export RUBYLIB=$HOME/skrypty1:$HOME/skrypty214 $LOAD_PATH15 => ["/home/polak/skrypty1", "/home/polak/skrypty2",

"/home/polak/.rvm/rubies/ruby -2.5.0/ lib/ruby/site_ruby /2.5.0", ...]

1617 2.5.0 :005 > exit18 $ ruby skrypt.rb19 Ten skrypt został uruchomiony z linii komend

Konsola ’irb’

Dr inż. Stanisław Polak 17

Język Ruby Narzędzia

Ruby w systemie Linux / macOSMenedżery wersji Ruby

Ruby Version Manager (RVM)

1 $ sudo apt -get update2 $ sudo apt -get install libgdbm -dev libncurses5 -dev automake

libtool bison libffi -dev3 $ gpg --keyserver hkp:// keys.gnupg.net --recv -keys 409

B6B1796C275462A1703113804BB82D39DC0E34 $ curl -sSL https ://get.rvm.io | bash -s stable5 $ source ~/.rvm/scripts/rvm6 $ echo "source ~/.rvm/scripts/rvm" >> ~/. bashrc

Instalacja

Rbenv

1 cd2 git clone https :// github.com/rbenv/rbenv.git ~/. rbenv3 echo ’export PATH="$HOME /.rbenv/bin:$PATH"’ >> ~/. bashrc4 echo ’eval "$(rbenv init -)"’ >> ~/. bashrc5 exec $SHELL67 git clone https :// github.com/rbenv/ruby -build.git ~/. rbenv/

plugins/ruby -build8 echo ’export PATH="$HOME /.rbenv/plugins/ruby -build/bin:$PATH"’

>> ~/. bashrc9 exec $SHELL

Instalacja

Interpreter Ruby

1 $ rvm install <nazwaInterpretera >2 $ rbenv install <nazwaInterpretera >

Instalacja

1 $ rvm list known #wyświetlenie (nazw) dostępnych implementacjiwraz z numerami ich wersji

2 $ rvm upgrade <nazwaImplementacji > # np. rvm upgrade ruby34 $ rbenv install --list #wyświetlenie (nazw) dostępnych

implementacji wraz z numerami ich wersji5 $ rbenv install <nazwaInterpretera >

Aktualizacja

1 $ rvm use <nazwaInterpretera > --default #lub rvm use x.x.x --default

2 $ rbenv global <nazwaInterpretera >

Określanie domyślnego interpretera

Dr inż. Stanisław Polak 18

Notatki

Notatki

Page 9: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Narzędzia

Ruby w systemie Linux / macOSWażniejsze implementacje

Implementacje w języku C (CRuby)I MRI (ang. Matz’s Ruby Interpreter)

I Używany w Ruby ¬ 1.8I Tworzone jest drzewo składnioweI Korzysta z „zielonych wątków”

I YARV (Yet Another Ruby VM)I Używany w Ruby ­ 1.9I Wirtualna maszyna RubyI Korzysta z wątków natywnych; używa GIL

(Global Interpreter Lock)I Oferuje kompilator JIT (Just-in-time) —

począwszy od wersji 2.6I Instalacja

1 $ rvm install ruby # instalacja najnowszej wersjiprodukcyjnej

2 $ rvm install ruby -head # instalacja najnowszejwersji deweloperskiej (testowej)

3 $ rvm install x.x.x # instalacja wersji o numerzex.x.x

InneI JRuby

I Implementacja w JavieI Używa wątków natywnych, brak GILI Używa kompilatora JITI Instalacja

1 $ rvm install jruby

I TruffleRubyI Korzysta z:

I Truffle — platforma do implementacjiwysokowydajnych środowisk językowychkorzystających z Javy oraz wirtualnej maszynyJavy

I GraalVM — wirtualna maszyna Javywyposażona w kompilator JIT o nazwie„Graal”

I Źródła: http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/

I Informacje o innych implementacjach —http://rvm.io/interpreters/

Dr inż. Stanisław Polak 19

Język Ruby Narzędzia

Ruby w systemie Linux / macOSPorównanie wydajności implementacji

1 def fibonacci(n)2 if n < 23 return n4 end5 return fibonacci(n - 2) + fibonacci(n - 1)6 end7 ## ###############8 def wątki9 i = 100 _000_000

10 2.times.map do11 Thread.new do12 50 _000_000.times { i -= 1 }13 end14 end.each (&: join) #Czekamy aż wszystkie wątki zakończą pracę15 # Znaczenie ’&: nazwa ’ - patrz slajd nr 6116 printf("Końcowa wartość i: %d\n", i)17 end

funkcje.rb

1 require ’benchmark ’2 load ’funkcje.rb’3 ## ###############4 czas_wykonania = Benchmark.realtime do |x|5 5.times { fibonacci (35) }6 end7 printf "Czas wykonania: %f\n", czas_wykonania8 ## ###############9 wątki()

skrypt.rb

1 $ rvm use ruby -2.6.12 $ time ruby skrypt.rb3 Czas wykonania: 10.2557804 Końcowa wartość i: 056 real 0m19 ,201s7 user 0m19 ,179s8 sys 0m0 ,013s9 $ time ruby --jit skrypt.rb # Włączona kompilacja JIT

10 Czas wykonania: 3.35290111 Końcowa wartość i: 01213 real 0m9 ,019s14 user 0m17 ,473s15 sys 0m0 ,684s16 # ###########################################17 $ rvm use 9.2.6.0 # Openjdk wersja "11.0.1"18 $ time ruby skrypt.rb19 Czas wykonania: 6.11213620 Końcowa wartość i: 464142852122 real 0m16 ,994s23 user 0m33 ,553s24 sys 0m0 ,313s25 $ time ruby -X-C skrypt.rb # Wyłączona kompilacja JIT26 Czas wykonania: 52.74284027 Końcowa wartość i: 99103692829 real 1m22 ,684s30 user 1m56 ,812s31 sys 0m0 ,340s32 # ###########################################33 $ rvm use truffleruby #GraalVM wersja "1.0.0 - rc13"34 $ time ruby skrypt.rb35 Czas wykonania: 2.04054336 Końcowa wartość i: 383583763738 real 0m4 ,596s39 user 0m7 ,361s40 sys 0m0 ,157s

Dr inż. Stanisław Polak 20

Notatki

Notatki

Page 10: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Narzędzia

RubyGems

I Standardowy menedżer pakietów (gemów) Rubiego — działa podobnie jak apt, yum, . . .I Dostępny wraz z Ruby ­ 1.9

Przykłady użycia

1 gem install rails # zainstaluj gem ’Ruby on Rails ’2 gem fetch rails #pobierz gem ’Ruby on Rails ’, ale go nie instaluj3 gem uninstall rails #usuń gem ’Ruby on Rails ’4 gem list --local #wyświetl zainstalowane gemy5 gem list --remote #wyświetl dostępne gemy6 gem search NAPIS --remote # przeszukaj listę dostępnych gemów7 gem rdoc --all #stwórz dokumentacj ę RDoc/RI dla wszystkich zainstalowanych gemów8 gem cleanup #usuń stare wersje zainstalowanych gemów

Dr inż. Stanisław Polak 22

Język Ruby Narzędzia

Tworzenie i generowanie dokumentacjiProgram „rdoc”

1 # The program takes an initial word or phrase from2 # the command line (or in the absence of a3 # parameter from the first line of standard4 # input). In then reads successive words or5 # phrases from standard input and reports whether6 # they are angrams of the first word.7 #8 # Author :: Dave Thomas (mailto:[email protected])9 # Copyright :: Copyright (c) 2002 The Pragmatic Programmers ,

LLC10 # License :: Distributes under the same terms as Ruby1112 # This class holds the letters in the original13 # word or phrase. The is_anagram ? method allows us14 # to test if subsequent words or phrases are15 # anagrams of the original.16 class Anagram1718 # Remember the letters in the initial word19 def initialize(text)20 @initial_letters = letters_of(text)21 end22 # Test to see if a new word contains the same23 # letters as the original24 def is_anagram ?(text)25 @initial_letters == letters_of(text)26 end

27 # Determine the letters in a word or phrase28 #29 # * all letters are converted to lower case30 # * anything not a letter is stripped out31 # * the letters are converted into an array32 # * the array is sorted33 # * the letters are joined back into a string34 def letters_of(text)35 text.downcase.delete(’^a-z’).split(’’).sort.join36 end37 end3839 tester = Anagram.new(ARGV.shift || gets)40 ARGF.each do |text|41 puts "Anagram! " if tester.is_anagram? text42 end

anagram.rb

1 $ rdoc # Generuj pliki ’.html ’2 $ rdoc --format=ri # Generuj pliki ’.ri ’3 $ rdoc --format=pot # Generuj plik ’rdoc.pot ’

Generowanie dokumentacji

Dr inż. Stanisław Polak 23

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 11: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Narzędzia

Wyświetlanie manualaProgram „ri”

1 $ ri --help2 Usage: ri [options] [names ...]34 Where name can be:56 Class | Module | Module :: Class78 Class:: method | Class#method | Class.method | method9

10 gem_name: | gem_name:README | gem_name:History1112 All class names may be abbreviated to their minimum unambiguous form. If a name13 is ambiguous , all valid options will be listed.1415 A ’.’ matches either class or instance methods , while #method16 matches only instance and :: method matches only class methods.1718 README and other files may be displayed by prefixing them with the gem name19 they’re contained in. If the gem name is followed by a ’:’ all files in the20 gem will be shown. The file name extension may be omitted where it is21 unambiguous.2223 For example:2425 ri Fil26 ri File27 ri File.new28 ri zip29 ri rdoc:README3031 Note that shell quoting or escaping may be required for method names containing32 punctuation:3334 ri ’Array .[]’35 ri compact \!3637 To see the default directories ri will search , run:3839 ri --list -doc -dirs40 ...

Dr inż. Stanisław Polak 24

Język Ruby Narzędzia

Debugowanie skryptu

1 a=12 b=23 c=34 puts a5 puts b6 puts c

skrypt.rb

1 $ gem install byebug2 $ byebug skrypt.rb3 [1, 6] in /home/polak/skrypt.rb4 => 1: a=15 2: b=26 3: c=37 4: puts a8 5: puts b9 6: puts c

10 (byebug) display a11 1: a = nil12 (byebug) next1314 [1, 6] in /home/polak/skrypt.rb15 1: a=116 => 2: b=217 3: c=318 4: puts a19 5: puts b20 6: puts c21 1: a = 1

Debuger „Byebug”

1 $ ruby -rdebug skrypt.rb #Załadowanie biblioteki "debug"2 Debug.rb3 Emacs support available.45 skrypt.rb:1:a=16 (rdb:1) list7 [-4, 5] in skrypt.rb8 => 1 a=19 2 b=2

10 3 c=311 4 puts a12 5 puts b13 (rdb:1) display a14 1: a =15 (rdb:1) break 316 Set breakpoint 1 at skrypt.rb:317 (rdb:1) cont18 Breakpoint 1, toplevel at skrypt.rb:319 skrypt.rb:3:c=320 1: a = 121 (rdb:1) p b22 223 (rdb:1) p c24 nil25 (rdb:1) next26 skrypt.rb:4: puts a27 1: a = 128 (rdb:1) cont29 130 231 3

Dr inż. Stanisław Polak 25

Notatki

Notatki

Page 12: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Narzędzia

Alternatywna konsola RubyProgram „pry”

Wybrane cechyI Przeglądanie kodu źródłowegoI Podświetlanie składniI Przeglądanie dokumentacjiI System pomocy, na żywoI Integracja powłoki poleceń (uruchamianie

edytorów, uruchomianie ’git’ oraz ’rake’ zpoziomu ’pry’)

I Możliwość debugowania kodu

1 a=12 binding.pry #pierwsza pułapka3 b=24 c=35 binding.pry #druga pułapka6 puts a7 puts b8 puts c

skrypt.rb

1 $ gem install pry # Instalacja ’pry ’2 $ gem install pry -doc # Rozszerzona obsługa dokumentacji dla ’

pry ’3 $ pry4 [1] pry(main)> puts "Hello World"5 Hello World6 => nil7 [2] pry(main)> exit8 $ ruby -r pry skrypt.rb # Uruchomienie w trybie ,,debug ’’9 1: a=1

10 => 2: binding.pry #pierwsza pułapka11 3: b=212 4: c=313 5: binding.pry #druga pułapka14 6: puts a15 7: puts b16 [1] pry(main)> a17 => 118 [2] pry(main)> b19 => nil20 [3] pry(main)> Ctrl+D21 From: /home/polak/skrypt.rb @ line 5 :2223 1: a=124 2: binding.pry #pierwsza pułapka25 3: b=226 4: c=327 => 5: binding.pry #druga pułapka28 6: puts a29 7: puts b30 8: puts c31 9:3233 [1] pry(main)>

Dr inż. Stanisław Polak 26

Język Ruby Zmienne

Definiowanie zmiennych

1 #stałe2 STALA=13 =>14 STALA=25 (irb):2: warning: already initialized constant STALA6 => 27 # definiowanie zmiennych8 a = 109 b = 20

10 c = 3011 d = 4012 a, b, c, d = 10, 20, 30, 4013 # identyfikacja typu14 d.kind of? Integer15 => true16 d.class17 => Integer18 #zmiana typu19 x = 1020 => 1021 x.class22 => Integer23 x = "hello"24 => "hello"25 x.class26 => String

1 y = 202 => 203 y.to f4 => 20.05 54321.to s #kod dziesiątkowy6 => "54321"7 54321.to s(2) #kod dwójkowy8 => "1101010000110001"9 54321.to s(16) #kod szesnastkowy

10 => "d431"11 54321.to s(8) #kod ósemkowy12 => "152061"

Konwersja wartości

Dr inż. Stanisław Polak 27

Notatki

Notatki

Page 13: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Zmienne

Zasięg zmiennych

1 x = 102 => 103 defined? x4 => "local -variable"5 $x = 106 => 107 defined? $x8 => "global -variable"9 loopcounter = 10

10 LoopCounter = 2011 $welcome = "Welcome to Ruby"12 gets13 hello14 => "hello\n"15 $16 => "hello\n"17 require ’English ’18 => true19 $LAST READ LINE20 => "hello\n"21 $$22 => 1740323 @@total = 024 @total = 1025 Stala=1

Dr inż. Stanisław Polak 28

Język Ruby Struktury kontrolne

Instrukcja warunkowa if

Wyrażenie „if”

1 if warunek [then]2 kod ...3 [elsif warunek [then]4 kod ...]...5 [else6 kod ...]7 end

Składnia

1 if 10 < 20 then2 print "10 jest mniejsze niż 20"3 end

Przykład użycia

Modyfikator „if”

1 kod if warunek

Składnia

1 print "10 jest mniejsze niż 20" if 10 < 20

Przykład użycia

1 liczba = 52 znak = if liczba > 03 ’dodatni ’4 elsif liczba < 05 ’ujemny ’6 else7 ’zero’8 end9 znak

10 => "dodatni"

Dr inż. Stanisław Polak 29

Notatki

Notatki

Page 14: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Struktury kontrolne

Instrukcja warunkowa unless

Wyrażenie „unless”

1 unless warunek [then]2 kod3 [else4 kod ]5 end

Składnia

1 unless str.nil?2 puts str.length3 end4 # W Ruby >= 2.3 powyższe linie można zapisać nastę

pująco:5 # puts str &. length

Przykład użycia

Modyfikator „unless”

1 kod unless warunek

Składnia

1 puts str.length unless str.nil?

Przykład użycia

Dr inż. Stanisław Polak 30

Język Ruby Struktury kontrolne

Instrukcja wyboru

1 ## ####### Forma 1 #########2 case wyrażenie3 [when wyrażenie [, wyrażenie ...] [then]4 kod ]...5 [else6 kod ]7 end89 ## ####### Forma 2 #########

10 case11 [when wyrażenie_logiczne [, wyrażenie_logiczne ...] [then]12 kod ]...13 [else14 kod ]15 end

Składnia

1 liczba = 72 case liczba3 when 1,2,3 # Wykonuje: 1 === liczba || 2 === liczba || 3 ===

liczba4 "mały"5 when 4,5,66 "średni"7 when 7,8,98 "duży"9 else

10 "olbrzymi"11 end12 => "duży"13 ## #########################14 a = 215 case16 when a == 1, a == 217 "a ma wartość jeden lub dwa"18 when a == 319 "a ma wartość trzy"20 else21 "Nie potrafię określić wartości zmiennej a"22 end23 => "a ma wartość jeden lub dwa"24 ## #########################25 case url26 when /http:/27 "protokół HTTP"28 ...29 else30 "nieznany protokół"31 end

Przykład użycia

Dr inż. Stanisław Polak 31

Notatki

Notatki

Page 15: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Struktury kontrolne

Pętle while oraz until1 while warunek [do]2 kod3 end45 begin6 kod7 end while warunek89 kod while warunek

Składnia pętli „while”

1 line=nil2 while line !~ /^$/ do line = gets.chomp end3 ## ######################4 i=15 while i < 36 puts i7 i += 1 #W Ruby nie ma instrukcji : ’++ zmienna ’ / ’zmienna --’, itp.8 j = 29 end

10 puts j #Wypisze: 211 ## ######################12 i=113 begin14 puts i15 i += 116 j = 217 end while i < 3 #Ta konstrukcja nie jest zalecana przez Matz -a18 puts j #Wypisze: 219 ## ######################20 line = gets.chomp while line !~ /^$/

1 until warunek [do]2 kod3 end45 until while warunek67 begin8 kod9 end until warunek

Składnia pętli „until

1 line=nil2 until line =~ /^$/ do line = gets.chomp end3 ## ######################4 i=15 until i >= 3 do6 puts i7 i += 18 j = 29 end

10 puts j #Wypisze: 211 ## ######################12 i=113 begin14 puts i15 i += 116 j = 217 end until i >= 3 #Ta konstrukcja nie jest zalecana przez Matz -a18 puts j #Wypisze: 219 ## ######################20 line = gets.chomp until line =~ /^$/

Dr inż. Stanisław Polak 32

Język Ruby Struktury kontrolne

Instrukcje break, redo oraz next

1 i = 02 while p "Wyrażenie ’while’"3 i += 14 printf "\ti=%d\n", i5 case i6 when 27 puts "\tWykonuję ’next’"8 next9 when 4

10 puts "\tWykonuję ’redo’"11 redo12 when 613 puts "\tWykonuję ’break’"14 break15 end16 puts "\tJestem na końcu ’while’"17 end18 puts ’Koniec ’

Na wyjściu

Wyrażenie ’while’i=1Jestem na końcu ’while’Wyrażenie ’while’i=2Wykonuję ’next’Wyrażenie ’while’i=3Jestem na końcu ’while’Wyrażenie ’while’i=4Wykonuję ’redo’i=5Jestem na końcu ’while’Wyrażenie ’while’i=6Wykonuję ’break’Koniec

Dr inż. Stanisław Polak 33

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 16: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Struktury kontrolne

Pętla loop

1 #Petla nieskończona2 loop do3 puts "Witaj"4 end56 #Petla skończona7 i = 18 loop do9 puts i

10 i += 111 j = 212 break if i > 313 end14 puts j # undefined local variable or method ‘j’

Dr inż. Stanisław Polak 34

Język Ruby Struktury kontrolne

Pętla for oraz metody iteracyjne

1 for i in 1..8 do2 puts i3 end4 # Powyższy kod jest równoważny:5 # (1..8).each{ |i| puts i }6 ## ############7 strs = ["abc\n", "cdae\n", "zzas\n", "aaaa\n"]8 strs.each{ |s| s.chop! }9 p strs

10 ## ############11 5.times { |i| puts i }12 ## ############13 2.upto(4) { |i| puts i }14 ## ############15 4.downto(2) { |i| puts i }16 ## ############17 0.step(10, 2) { |i| puts i }18 ## ############19 0.step(10, 2) do |i|20 puts i21 redo22 end

Na wyjściu

Dr inż. Stanisław Polak 35

Notatki

Notatki

Page 17: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Typy liczboweI Integer

1 2 - 3 * 22 =>-43 1.hour + 90. minutes + 1. minute #Dostępne w RoR lub po

wykonaniu "require ’active_support /all ’"4 => 1 hour and 91 minutes5 1111111111111111111111*4006 => 444444444444444444444400

I FloatI Rational

1 Rational (1,3) + Rational (1,2) # 13 + 1

2 = 56

2 => (5/6)3 0.1r #Składnia dostępna począwszy od wersji 2.14 => (1/10)5 0.1r * 36 => (3/10)

I Complex

1 Complex (1,2)+Complex (2,3) # <=> (1+2i)+(2+3i)=(3+5i)2 => (3+5i)3 42ri #Składnia dostępna począwszy od wersji 2.14 => (0+(42/1)*i)

I Konwersje

1 Integer (10.898)2 => 103 Integer (0 b01110101) # konwersja z kodu binarnego4 => 1175 Integer (01231) # konwersja z kodu ó semkowego6 => 6657 Integer (0 xaabb) # konwersja z kodu szesnastkowego8 => 437079 Float (10)

10 =>10.011 Integer("aaa")12 ArgumentError: invalid value for Integer (): "aaa"13 Float("aaa")14 ArgumentError: invalid value for Float (): "aaa"

Dr inż. Stanisław Polak 38

Język Ruby Typy danych Typy podstawowe

Wyrażenia regularne

1 name = "Matz"2 name =~ /([[: lower :]]{2})/3 $‘4 => "M"5 $16 => "at"7 $’8 => "z"9 #Inne sposoby konstrukcji wyrażenia regularnego

10 name =~ %r|([[: lower :]]{2})|11 => 112 re = Regexp.new("([[: lower :]]{2})")13 md = re.match(name)14 => #<MatchData :0 xb7d41054 >15 md.pre match16 => "M"17 md.value at 118 => "at"19 md.post match20 => "z"

Dr inż. Stanisław Polak 39

Notatki

Notatki

Page 18: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Przedziały

1 1..10 # Zakres od 1 do 102 1...10 # Zakres od 1 do 934 (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]5 (1...10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9]67 (’a’..’l’).to_a # => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]8 (’Z’..’a’).to_a # => ["Z", "[", "\\" , "]", "^", "_", "‘", "a"]9

10 (’cab’..’car’).to_a # => [" cab", "cac", "cad", "cae", "caf", "cag", "cah", "cai", "caj", "cak", "cal", "cam", "can", "cao", "cap", "caq", "car "]

Dr inż. Stanisław Polak 40

Język Ruby Typy danych Typy podstawowe

PrzedziałyMetody

1 words = ’cab’..’car’2 words.min3 => "cab"4 words.max5 => "car"6 words.include?(’can’)7 => true8 words.reject {| subrange| subrange < ’cal’}9 => ["cal", "cam", "can", "cao", "cap", "caq", "car"]

10 words.each {|word| puts "Hello " + word}11 Hello cab12 Hello cac13 ...14 Hello car

Dr inż. Stanisław Polak 41

Notatki

Notatki

Page 19: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

PrzedziałyPrzykłady zastosowania

1 while input = gets2 puts input + " triggered" if input =~ /start /..

input =~ /end/3 end

Na wyjściu

12startstarttriggered11triggered22triggeredendendtriggered12

1 score = 702 result =3 case score4 when 0..40: "Nie zaliczył (oblał test)"5 when 41..60: "Zaliczył"6 when 61..70: "Zaliczył z wysokim wynikiem"7 when 71..100: "Zaliczył z wyróżnieniem"8 else "Nieprawidłowy wynik testu"9 end

10 puts result

Dr inż. Stanisław Polak 42

Język Ruby Typy danych Typy podstawowe

Tablice zwykłe

1 days_of_week = Array.new(7)2 => [nil , nil , nil , nil , nil , nil , nil]3 days_of_week = Array.new(7, "today")4 => ["today", "today", "today", "today", "today", "today", "today"]5 days_of_week = Array[ "Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun" ]6 #lub7 days_of_week = [ "Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun" ]8 => ["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"]9 days_of_week.empty?

10 => false11 days_of_week.size12 => 713 days_of_week.length14 => 715 days_of_week[0]16 => "Mon"17 days_of_week.at(0)18 => "Mon"19 days_of_week.first20 => "Mon"21 days_of_week [0].class22 => String23 days_of_week.index("Wed")24 => 225 days_of_week[1, 3]26 => ["Tues", "Wed", "Thu"]27 days_of_week[1..3]28 => ["Tues", "Wed", "Thu"]

Dr inż. Stanisław Polak 43

Notatki

Notatki

Page 20: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Tablice zwykłe c.d.

1 matrix = [[1,2,3],[3,4,5],[5,6,7]]2 matrix [1]3 => [3, 4, 5]4 matrix[1][1]5 => 46 matrix [1,1]7 => [[3, 4, 5]]8 ## ##########################################9 operating_systems = ["Fedora", "SuSE", "RHEL", "Windows", "

macOS"]10 linux_systems = ["RHEL", "SuSE", "PCLinuxOS", "Ubuntu", "

Fedora"]11 operating_systems | linux_systems12 => ["Fedora", "SuSE", "RHEL", "Windows", "macOS", "PCLinuxOS",

"Ubuntu"]13 operating_systems & linux_systems14 => ["Fedora", "SuSE", "RHEL"]15 operating_systems - linux_systems16 => ["Windows", "macOS"]

17 days1 = ["Mon", "Tue", "Wed"]18 days2 = ["Thu", "Fri", "Sat", "Sun"]19 days = days1 + days220 days21 => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]22 days123 => ["Mon", "Tue", "Wed"]24 ## ##########################################25 days1 = ["Mon", "Tue", "Wed"]26 days2 = ["Thu", "Fri", "Sat", "Sun"]27 days = days1.concat(days2)28 => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]29 days30 => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]31 days132 => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]3334 ## ##########################################35 days1 = ["Mon", "Tue", "Wed"]36 days2 = ["Thu", "Fri", "Sat", "Sun"]37 days = days1 << days238 days39 => ["Mon", "Tue", "Wed", ["Thu", "Fri", "Sat", "Sun"]]40 days141 => ["Mon", "Tue", "Wed", ["Thu", "Fri", "Sat", "Sun"]]

Dr inż. Stanisław Polak 44

Język Ruby Typy danych Typy podstawowe

Tablice asocjacyjne

1 hash = { "jeden" => 1, "dwa" => 2, "trzy" => 3 }2 hash["jeden"]3 => 14 hash1 = {jeden:1, dwa:2, trzy :3} #Składnia dostępna począwszy od wersji 1.95 => {: jeden=>1, :dwa=>2, :trzy=>3}6 hash1[:jeden]7 => 18 histogram = Hash.new(0)9 => {}

10 histogram["Ala"]11 => 012 histogram["Ala"] += 113 => 114 histogram["Ala"]15 => 116 hash.has key?("jeden")17 => true18 hash.has value?("jeden")19 => false

Dr inż. Stanisław Polak 45

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 21: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Uporządkowane tablice asocjacyjne

1 h = {"c" => 3, "a" => 1, "b" => 2}2 h.each do |k, v|3 p [k, v]4 end56 #Wynik działania:7 # Ruby 1.9+ Ruby 1.88 ["c", 3] ["a", 1]9 ["a", 1] ["b", 2]

10 ["b", 2] ["c", 3]

1 h = {}2 h["a"] = "foo"3 h["b"] = "bar"4 p h5 # Na wyjściu:6 {"a"=>"foo", "b"=>"bar"}78 h["a"] = nil9 p h

10 #Na wyjściu:11 {"a"=>nil , "b"=>"bar"}1213 h.delete("a")14 h["a"] = "foo"15 p h16 #Na wyjściu:17 {"b"=>"bar", "a"=>"foo"}

Dr inż. Stanisław Polak 46

Język Ruby Typy danych Typy podstawowe

Łańcuchy znakówTworzenie i formatowanie

1 ## ##### tworzenie łańcucha #######2 myString = String.new3 => ""4 myString = String.new("This is my string. Get your own string")5 myString = String("This is also my string") #metoda ’String ’

jest metodą modułu "Kernel" - konwersja do typunapisowego

6 myString = "This is also my string"7 myString = ’This is also my string’8 ## ##### wypisanie łańcucha #######9 ’’#{myString} #{1+3}’’ lub %Q&#{ myString} #{1+3}& lub %&#{

myString} #{1+3}& lub %[#{ myString} #{1+3}]10 => "This is also my string 4"11 ’#{myString}’ lub %q&#{ myString}& lub %q(#{ myString})12 => "\#{ myString}"13 ‘ls‘ lub %x&ls& lub %x{ls}14 => Wynik wykonania komendy ’ls’15 ## ##### składnia HereDocs #######16 myText= <<DOC17 118 #{myString}19 DOC20 DOC21 => "1\nThis is also my string\n DOC\n"22 myText= <<-DOC23 124 #{myString}25 DOC26 => "1\nThis is also my string\n"

27 ## ##### Tworzenie tablicy napisów #######28 %w(1 2 aaa)29 => ["1", "2", "aaa"]30 ## ##### Formatowanie łańcucha #######31 a=132 b=233 "a=%d" % a34 => "a=1"35 "a=%d, b=%d" % [a,b]36 => "a=1, b=2"37 "c=%{c}, d=%{d}" % {:c=>3,:d=>4}38 => "c=3,d=4"39 ## ############# Wybrane metody ###############40 myString = "Hello"41 myString.length42 => 543 myString.size44 => 545 myString.empty?46 => false47 myString.sub(’H’,’h’)48 => "hello"49 myString50 => "Hello"51 myString.sub!(’H’,’h’)52 => "hello"53 myString54 => "hello"55 myString.object_id56 => 956512057 myString.sub!(’h’,’H’)58 => "Hello"59 myString.object_id60 => 9565120

Dr inż. Stanisław Polak 47

Notatki

Notatki

Page 22: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Łańcuchy znakówŁączenie, dostęp do fragmentów oraz porównywanie

1 ## ############# łączenie ###############2 myString = "Welcome " + "to " + "Ruby!" # konkatenacja (nie modyfikuje łańcucha z lewej)3 => "Welcome to Ruby!"4 myString = "Welcome " "to " "Ruby!" #jw.5 => "Welcome to Ruby!"6 myString = "Welcome ".concat("to ").concat("Ruby!") #dołącza do łańcucha z lewej ( modyfikuje go)7 => "Welcome to Ruby!"8 myString = "Welcome " << "to " << "Ruby!" #jw.9 => "Welcome to Ruby!"

10 ## ############# dostęp do fragmentów ###############11 myString["Ruby"]12 => "Ruby"13 myString["Perl"]14 => nil15 myString[3] #Ruby 1.9+16 => "c"17 myString[3].ord #Ruby 1.9+18 => 9919 myString[3].chr #Ruby 1.820 => "c"21 myString[11, 4]22 => "Ruby"23 myString[0..6]24 => "Welcome"25 myString[/[A-Z]/]26 => "W"27 myString.index(’’Ruby’’)28 => 11

Dr inż. Stanisław Polak 48

Język Ruby Typy danych Typy podstawowe

Łańcuchy znakówZastępowanie, substytucja, wstawianie

1 ## ##### podmiana #######2 myString = "Welcome to JavaScript!"3 myString["JavaScript"]= "Ruby"4 puts myString5 => "Welcome to Ruby!"6 myString = "Welcome to JavaScript!"7 myString[10] = "Ruby"8 puts myString9 => "Welcome toRubyJavaScript!"

10 myString = "Welcome to JavaScript!"11 myString[8..20] = "Ruby"12 puts myString13 => "Welcome Ruby!"14 ## ##### substytucja #######15 myString = "Welcome to PHP"16 myString.gsub("PHP", "Ruby")17 => "Welcome to Ruby"18 myString.replace("Goodbye to PHP!")19 => "Goodbye to PHP!"20 ## ##### powielanie #######21 myString * 322 => "Goodbye to PHP!Goodbye to PHP!Goodbye to PHP!"23 ## ##### wstawianie #######24 myString1 = "Paris in Spring"25 myString2 = "Paris in Spring"26 myString1 [8]=" the" # podmiana , a nie wstawienie przed27 => " the"28 myString129 => "Paris in theSpring"30 myString2.insert(8, " the")31 => "Paris in the Spring"32 myString233 => "Paris in the Spring"

Dr inż. Stanisław Polak 49

Notatki

Notatki

Page 23: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Łańcuchy znakówKonwersja

1 myArray = Array("ABCDEFGHIJKLMNOP")2 => ["ABCDEFGHIJKLMNOP"]3 myArray = "ABCDEFGHIJKLMNOP".split4 => ["ABCDEFGHIJKLMNOP"]5 myArray = "ABCDEFGHIJKLMNOP".split(//)6 => ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"]7 "1000".to i8 => 10009 Integer("aaa")

10 # ArgumentError : invalid value for Integer (): "aaa"11 "aaa".to i #Nie wyrzuca wyjątku12 => 0

Dr inż. Stanisław Polak 50

Język Ruby Typy danych Typy podstawowe

Łańcuchy znakówNiemodyfikowalne napisy

1 # frozen string literal: true2 napis = "Stanisław"3 puts napis << " Polak" # RuntimeError : can ’t modify frozen String4 puts napis.dup << " Polak" #Wypisze: Stanisław Polak

Dr inż. Stanisław Polak 51

Notatki

Notatki

Page 24: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Symbole

1 # Tworzenie symboli2 s1 = :Polak3 s2 = :"Polak"4 %s(Stanisław Polak)5 => :"Stanisław Polak"6 # Tworzenie tablicy symboli7 %i(Stanisław Polak) #Dostępne w Ruby 2.0+8 => [: Stanisław, :Polak]9 ## ################

10 str1 = "Stanisław"11 str2 = "Stanisław"12 s1.object id == s2.object id13 => true14 str1.object id == str2.object id15 => false16 ## #############################17 "Stanisław" << " Polak"18 => "Stanisław Polak"19 :"Stanisław" << :" Polak"}20 NoMethodError: undefined method ‘<<’ for :Stanisław:Symbol21 ###############################22 :" Stanisław Polak".to s23 => "Stanisław Polak"24 "Stanisław Polak ".to sym25 => :" Stanisław Polak"26 ###############################27 :" Stanisław Polak".length # ⇔ :" Stanisław Polak".to_s.length28 =>1529 :Polak.gsub(’P’,’p’)30 NoMethodError: undefined method ‘gsub’ for :Polak:Symbol

1 key = "Jabłko"2 => "Jabłko"3 histogram[key] = 104 => 105 histogram[key]6 => 107 key.sub!("o", "a")8 => "Jabłka"9 key

10 => "Jabłka"11 histogram[key]12 => nil13 histogram["Jabłko"]14 => 1015 ## ########################16 key=:Jabłko17 => :Jabłko18 histogram[key] = 1019 => 1020 key.sub!("o", "a")21 NoMethodError: undefined method ‘sub!’ for :Jabłko:Symbol ...22 histogram[key]23 => 10

Dr inż. Stanisław Polak 52

Język Ruby Typy danych Typy podstawowe

Typ logiczny oraz pusty

1 a = ""2 a.nil?3 => false4 a = []5 a.nil?6 => false7 a = 08 a.nil?9 => false

10 a = nil11 a.nil?12 => true13 if 0 and [] and ’’’’14 "True"15 else16 "False"17 end18 => "True"19 if false or nil20 "True"21 else22 "False"23 end # => "False"

Dr inż. Stanisław Polak 53

Notatki

Notatki

Page 25: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Typy danych Typy podstawowe

Porównywanie wartości

1 #Przykład ze strony http :// stackoverflow .com/questions/7156955/ whats -the -difference -between -equal -eql -and

2 def eq(a, b)3 puts "#{[a, ’==’, b]} : #{a == b}"4 puts "#{[a, ’.eql?’, b]} : #{a.eql?(b)}"5 puts "#{[a, ’===’, b]} : #{a === b}"6 puts "#{[a, ’.equal?’, b]} : #{a.equal?(b)}"7 end89 eq(Object.new , Object.new)

10 eq(’all’, ’all’)11 eq(:all , :all)12 eq(3, 3)13 eq(1, 1.0)

Na wyjściu[#<Object:0x000000025e11c0>, "==",

#<Object:0x000000025e1198>] : false[#<Object:0x000000025e11c0>, ".eql?",

#<Object:0x000000025e1198>] : false[#<Object:0x000000025e11c0>, "===",

#<Object:0x000000025e1198>] : false[#<Object:0x000000025e11c0>, ".equal?",

#<Object:0x000000025e1198>] : false["all", "==", "all"] : true["all", ".eql?", "all"] : true["all", "===", "all"] : true["all", ".equal?", "all"] : false[:all, "==", :all] : true[:all, ".eql?", :all] : true[:all, "===", :all] : true[:all, ".equal?", :all] : true[3, "==", 3] : true[3, ".eql?", 3] : true[3, "===", 3] : true[3, ".equal?", 3] : true[1, "==", 1.0] : true[1, ".eql?", 1.0] : false[1, "===", 1.0] : true[1, ".equal?", 1.0] : false

Dr inż. Stanisław Polak 54

Język Ruby Podprogramy Funkcje

Funkcje

1 ## ##################2 # Definiowanie funkcji3 ## ##################4 def nazwa funkcji(par1, par2=wartość domyślna, ...)5 ...6 return wartość7 end8 ## #############################9 def good_bye(*guys)

10 "Do widzenia " + guys.join(" i ")11 end1213 ## #################14 #Wywoływanie funkcji15 ## #################1617 nazwa funkcji(arg1,arg2,...)18 ## #############################19 good_bye("Stanisławie","Marcinie")20 => "Do widzenia Stanisławie i Marcinie"

1 def funkcja(a=1,b:2,c:3)2 puts a3 puts b4 puts c5 end67 funkcja (1) #Wypisze: 1 2 3 w osobnych liniach8 funkcja (1,1) #... wrong number of arguments (2 for

0..1) ( ArgumentError )9 funkcja(c:20,b:10) #Wypisze: 1 10 20 w osobnych

liniach10 argumenty = { c:200,b:100 }11 funkcja(3,**argumenty) #Wypisze: 3 100 200 w

osobnych liniach12 def moja_funkcja((a,b))13 p a: a, b: b14 end15 moja_funkcja ([1 ,2]) #Wypisze: {:a=>1, :b=>2}

Dr inż. Stanisław Polak 55

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 26: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Podprogramy Bloki

Przykłady

1 # definiowanie bloków2 {|x,y,z| x + y + z }3 do |x,y,z|4 x + y + z5 end6 # przekazywanie bloku jako parametru wywołania metody7 a = [1,2,3].reject{|e| e.odd?}8 #przekształcenie w obiekt9 odd = lambda {|e| e.odd?}

10 odd = ->(e){e.odd?} #Składnia dostępna począwszy od wersji 1.9. "()" można pominąć11 even_numbers = [1,2,3]. reject &odd12 odd_number = [1,2,3]. select &odd13 odd.call(3)14 => true15 odd[3] # metoda ’[]’ - alias metody ’call ()’16 => true17 odd.(3) #Składnia dostępna począwszy od wersji 1.918 => true

Dr inż. Stanisław Polak 57

Język Ruby Podprogramy Bloki

Przykłady

1 def dwarazy2 yield3 yield4 end5 dwarazy { puts "Witaj" } #można również wywołać tak: dwarazy () { puts "Witaj" }6 #Na wyjściu:7 Witaj8 Witaj9

10 def dwarazy11 yield 112 yield 213 end14 dwarazy {|i| puts "#{i}. raz: Witaj"}15 #Na wyjściu:16 1. raz: Witaj17 2. raz: Witaj1819 def dwarazy(&blok)20 blok.call 1 # zmienna ’blo21 blok.call 222 end23 dwarazy {|i| puts "#{i}. raz: Witaj"}24 #Na wyjściu25 1. raz: Witaj26 2. raz: Witaj27 =begin28 Można również wywołać tak:29 dwarazy () {|i| puts "#{i}. raz: Witaj"}30 ale nie tak:31 dwarazy( {|i| puts "#{i}. raz: Witaj"} )32 =end

Dr inż. Stanisław Polak 58

Notatki

Notatki

Page 27: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Podprogramy Bloki

Argumenty bloków

1 i = "foo"2 j = "foo"3 puts "Przed blokiem: i = #{i}"4 puts "Przed blokiem: j = #{j}"5 3.times do |i|6 puts "i = #{i}"7 j = i8 k = 29 end

10 puts "Poza blokiem: i = #{i}"11 puts "Poza blokiem: j = #{j}"12 puts "Poza blokiem: k = #{k}"

Wynik dla Ruby ­ 1.9

Przed blokiem: i = fooPrzed blokiem: j = fooi = 0i = 1i = 2Poza blokiem: i = fooPoza blokiem: j = 2’<main>’: undefined localvariable or method ‘k’ formain:Object (NameError)

Wynik dla Ruby 1.8

Przed blokiem: i = fooPrzed blokiem: j = fooi = 0i = 1i = 2Poza blokiem: i = 2Poza blokiem: j = 2undefined local variable ormethod ‘k’ for main:Object (NameError)

Dr inż. Stanisław Polak 59

Język Ruby Podprogramy Bloki

Zmienne lokalne dla bloków

1 j = 22 jj = 23 a = lambda {|;jj| j = 1; jj = 1} #Składnia dostępna począwszy od wersji 1.94 a.call()5 puts j # 16 puts jj # 2

Dr inż. Stanisław Polak 60

Notatki

Notatki

Page 28: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Podprogramy Bloki

Obiekt „Proc”

1 ## ####### Obiekt ’Proc ’ #############2 p = Proc.new { puts "Hello World" }3 p = proc {puts "Hello World"} #To samo co wyżej4 # proc <=> lambda , dla Ruby < 1.95 # proc <=> Proc.new , dla Ruby >= 1.96 p.call # wypisze ’Hello World ’7 p.class # zwróci ’Proc ’8 ## ############ Bloki #################9 { puts "Hello World"} #Błąd składniowy

10 a = { puts "Hello World"} #Błąd składniowy11 [1,2,3]. each {|x| puts x/2} #OK12 ## ################################13 def metoda(proc1 ,proc2)14 proc1.call15 proc2.call16 end17 a = Proc.new { puts "Pierwszy proc"}18 b = Proc.new { puts "Drugi proc"}19 metoda(a,b) #OK20 metoda{puts "Pierwszy proc" }{puts "Drugi proc"} #Błąd skł

adniowy

21 p = proc {|x| puts x}22 l = lambda {|x| puts x}23 puts p #<Proc :0 x00000001bca0d8@a .rb:1>24 puts l ##<Proc :0 x00000001bca0b0@a .rb:2 (lambda)>25 p.call #Zwraca nil26 l.call # ArgumentError : wrong number of arguments (0

for 1)27 p.call (1,2) #Wypisze: 1, pozostałe argumenty są

ignorowane28 l.call (1,2) # ArgumentError : wrong number of arguments

(2 for 1)29 ## ################################30 def metoda_lambda31 l = lambda { return } # ’return ’ - " wyskakujemy " z ’

lambda ’32 l.call33 puts "Hello world"34 end3536 def metoda_proc37 p = proc { return } #’return ’ - " wyskakujemy " z ’

metoda_proc ’38 p.call39 puts "Hello world"40 end4142 metoda_lambda #Wypisze: Hello World43 metoda_proc #Nic nie wypisze

Dr inż. Stanisław Polak 61

Język Ruby Podprogramy Bloki

Przekształcanie metody w obiekt ’Proc’

Wybieranie liczb nieparzystych

1 ## ##########2 # Dwuetapowo3 ## ##########4 odd = :odd?.to proc # Zmienna ’odd ’ zawiera obiekt klasy ’Proc ’, reprezentuj ący metodę o nazwie takiej

jak podany symbol5 p odd #Wypisze: <Proc :0x...(&: odd ?)6 p [1, 2, 3]. select (&odd) #Wypisze: [1, 3]7 ## ###########################################8 # zmienna = : nazwa_metody .to_proc}9 # obiekt.iterator (& zmienna)

10 # m11 # obiekt.iterator (&: nazwa_metody )12 ## ############13 # Jednoetapowo14 ## ############15 p [1, 2, 3]. select (&:odd?) #Wypisze: [1, 3]16 ## #############################################17 # obiekt.iterator (&: nazwa_metody ) ⇔ obiekt.iterator {| arg| arg. nazwa_metody }18 # operator ’&’ powoduje przekazanie nazwy metody do iteratora19 ## #############################################

Bez użycia bloku — z bezpośrednim użyciem obiektu ’Proc’

1 p [1, 2, 3]. select {|e| e.odd?} #Wypisze: [1, 3]

Z użyciem bloku

Dr inż. Stanisław Polak 62

Notatki

Notatki

Page 29: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Podprogramy Bloki

Domknięcia

1 =begin2 funkcja wykorzystuje trzy zmienne:3 ’y’ - dostępną dla użytkownika4 ’x’ - dostępną tylko wewnątrz funkcji ’mnozenie_przez ()’5 ’z’ - dostępną tylko wewnątrz funkcji ’mnozenie_przez ()’6 =end7 ## ##########################################################8 def mnozenie_przez(x)9 z=0

10 lambda {|y| z+= 1 ; printf "z=%d, %d*%d=",z,x,y; return x*y}11 end12 ## ##########################################################13 iloczyn_5_przez = mnozenie_przez (5) # Parametrowi ’x’ jest przypisywana wartość 514 iloczyn_6_przez = mnozenie_przez (6) # Parametrowi ’x’ jest przypisywana wartość 615 ## ##########################################################16 puts iloczyn_5_przez #Wypisze: #<Proc :0 x00000000c0de38@lambda .rb:8 (lambda)>17 x=1018 y=2019 z=3020 puts iloczyn_5_przez.call (10) # Wypisze: z=1, 5*10=5021 puts iloczyn_5_przez.call (11) # Wypisze: z=2, 5*11=5522 puts iloczyn_6_przez.call (12) # Wypisze: z=1, 6*12=7223 ## ##########################################################24 puts x #Wypisze: 1025 puts y #Wypisze: 2026 puts z #Wypisze: 20

1Fragment kodu, w którym zmienne lokalne zachowują swoją tożsamość

Dr inż. Stanisław Polak 63

Język Ruby Programowanie funkcyjne

Programowanie imperatywne a programowanie funkcyjne

Programowanie imperatywneI Skupia się na „jak”I Programy zawierają listę instrukcji, które

„mówią” komputerowi, co zrobić z danymiwejściowymi

Programowanie funkcyjneI Skupia się na „co”I Rozkłada problem w zestaw funkcji

Functional programming is like describing your problem to a mathematician. Imperative pro-gramming is like giving instructions to an idiot

(arcus, #scheme on Freenode)

1 n = 12 num_elements = 03 sum = 04 while num_elements < 105 if (n**2 % 5).zero?6 sum += n7 num_elements += 18 end9 n += 1

10 end11 sum12 => 275

Podejście imperatywne

1 (1.. Float :: INFINITY).lazy.select { |x| (x**2 % 5).zero? }.take (10).inject (:+)

2 => 275

Podejście funkcyjne

Dr inż. Stanisław Polak 64

Notatki

Notatki

Page 30: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Zasady

Nie modyfikuj zmiennych

Nie

1 indeksy = [1, 2, 3]2 indeksy << 43 ## ######################4 hasz = {:a => 1, :b => 2}5 hasz[:c] = 36 ## ######################7 napis = "witaj"8 napis.gsub !(/t/, ’l’)

Tak

1 indeksy = [1, 2, 3]2 wszystkie_indeksy = indeksy + [4]3 ## ######################4 hasz = {:a => 1, :b => 2}5 nowy_hasz = hasz.merge (:c => 3)6 ## ######################7 napis = "witaj"8 nowy_napis = napis.gsub(/t/, ’l’)

Dr inż. Stanisław Polak 65

Język Ruby Programowanie funkcyjne Zasady

Bloki jako funkcje wyższego rzędu

1 open("/etc/passwd") {|plik| puts plik.size}

Funkcja, która zawiera „funkcję” na liście argumentów

1 def dodawacz(a)2 proc {|b| a + b}3 end4 dodawacz5 = dodawacz (5)5 puts dodawacz5.call (3) #Wypisze: 8

Funkcja, która zwraca „funkcję”

Dr inż. Stanisław Polak 66

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 31: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Zasady

Częściowe zastosowanie funkcji oraz rozwijanie funkcji

1 suma = proc { |x, y, z| (x||0) + (y||0) + (z||0) }2 p suma.call(1, 2, 3) # 63 p suma[1, 2, 3] # 64 ## ############################5 # Częściowe zastosowanie funkcji (ang. partial function

application )6 suma_partial = proc { |x, y| proc { |z| x + y + z } }7 p suma_partial.call(1, 2).call (3) # 68 p suma_partial [1, 2][3] # 69 ## ############################

10 # Rozwijanie "funkcji" (ang. currying)11 suma_curry= proc { |x| proc { |y| proc { |z| x + y + z }

} }12 p suma_curry.call (1).call (2).call (3) # 613 p suma_curry [1][2][3] # 614 p suma.curry[1][2][3] # 615 ## ############################16 f = proc { |x, y, z| [x, y, z] }17 p f[4, 5, 6] # [4, 5, 6]18 p f[4][5 , 6] # nil19 p f[4, 5][6] # nil20 p f[4][5][6] # undefined method ‘[]’ for nil:NilClass (

NoMethodError )2122 g = f.curry23 p g[4, 5, 6] # [4, 5, 6]24 p g[4][5 , 6] # [4, 5, 6]25 p g[4, 5][6] # [4, 5, 6]26 p g[4][5][6] # [4, 5, 6]27 p g[4] # #<Proc :0 x00562b3a477028 >2829 gg = f.curry(2)

30 p gg[4, 5, 6] # [4, 5, 6]31 p gg[4][5 , 6] # [4, 5, 6]32 p gg[4, 5][6] # nil33 p gg [4][5][6] # nil34 p gg[4] # #<Proc :0 x00555ebc5edbc8 >3536 h = g[1] # ’x’ otrzymuje wartość 137 p h[4, 5, 6] # [1, 4, 5]38 p h[4, 5] # [1, 4, 5]39 p h[4][5] # [1, 4, 5]40 p h[4] # #<Proc :0 x000000019404c0 >4142 hh = gg[1] # ’x’ otrzymuje wartość 143 p hh[4, 5, 6] # [1, 4, 5]44 p hh[4, 5] # [1, 4, 5]45 p hh [4][5] # nil46 p hh[4] # [1, 4, nil]4748 i = h[2] # ’y’ otrzymuje wartość 249 p i[4, 5, 6] # [1, 2, 4]50 p i[4, 5] # [1, 2, 4]51 p i[4] # [1, 2, 4]52 p i # #<Proc :0 x00558a3d2a2b38 >5354 ii = hh[2] # ’y’ otrzymuje wartość 255 p ii[4, 5, 6] # wrong number of arguments (given 3,

expected 1..2) ( ArgumentError )56 p ii[4, 5] # nil57 p ii[4] # nil58 p ii # [1, 2, nil]5960 j = i[3] # ’z’ otrzymuje wartość 361 p j # [1, 2, 3]6263 jj = ii[3]64 p jj #nil

Dr inż. Stanisław Polak 67

Język Ruby Programowanie funkcyjne Zasady

Rozwijanie funkcjiPrzykład użycia

1 ## #################################2 # Normal definitions

3 # pattern:∑

f (n) for n ∈ [a . . . b]

4 ## #################################5 sum_ints = lambda do |a,b|6 s = 0 ; a.upto(b){|n| s += n } ; s7 end89 sum_of_squares = lambda do |a,b|

10 s = 0 ; a.upto(b){|n| s += n**2 } ;s11 end1213 sum_of_powers_of_2 = lambda do |a,b|14 s = 0 ; a.upto(b){|n| s += 2**n } ; s15 end1617 puts sum_ints .(1 ,5) #=> 1518 puts sum_of_squares .(1 ,5) #=> 5519 puts sum_of_powers_of_2 .(1 ,5) #=> 6220 ## ##########################################21 # Some refactoring to make some abstraction22 # Passing the sum mechanism itself23 ## ##########################################24 sum = lambda do |f,a,b|25 s = 0 ; a.upto(b){|n| s += f.(n) } ; s26 end

27 puts sum[lambda {|x| x},1,5] #=> 1528 puts sum[lambda {|x| x**2},1,5] #=> 5529 puts sum[lambda {|x| 2**x},1,5] #=> 6230 ## #################################31 # More refactoring using currying32 ## #################################3334 # generate the currying35 currying = sum.curry3637 # Generate the partial functions38 sum_ints = currying[lambda {|x| x}]39 sum_of_squares = currying[lambda {|x| x**2}]40 sum_of_powers_of_2 = currying[lambda {|x| 2**x}]4142 puts sum_ints [1,5] #=> 1543 puts sum_of_squares [1,5] #=> 5544 puts sum_of_powers_of_2 [1,5] #=> 62

Źródło: http://blog.khd.me/ruby/ruby-currying/

Dr inż. Stanisław Polak 68

Notatki

Notatki

Page 32: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Zasady

Unikanie skutków ubocznych

Nie

1 [1,2,3]. each do |x|2 #kod z efektami ubocznymi3 end4 for i in [1,2,3] do5 #kod z efektami ubocznymi6 end

Dr inż. Stanisław Polak 69

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Metoda map()

Nie

1 wynik = []2 [1,2,3,4]. each do |x|3 wynik << x*24 end5 wynik #[2, 4, 6, 8]

Tak

1 wynik =[1,2,3,4].map do |x|2 x*23 end #[2, 4, 6, 8]

Dr inż. Stanisław Polak 70

Notatki

Notatki

Page 33: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Metoda select()

Nie

1 wynik = []2 [1,2,3,4]. each do |x|3 wynik << x if x > 24 end5 wynik #[3 ,4]

Tak

1 wynik =[1,2,3,4]. select do |x|2 x > 23 end #[3, 4]

Dr inż. Stanisław Polak 71

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Metoda detect()

Nie

1 wynik = nil2 [1,2,3,4]. each do |x|3 if x > 24 wynik = x5 break6 end7 end8 wynik #3

Tak

1 wynik =[1,2,3,4]. detect do |x|2 x > 23 end #3

Dr inż. Stanisław Polak 72

Notatki

Notatki

Page 34: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Metoda inject()

Nie

1 suma = 02 [1,2,3,4]. each do |x|3 suma += x4 end5 suma #10

Tak

1 suma = [1,2,3,4]. inject (0) do |aku , x|2 aku+x3 end #104 ## ###############################5 suma = [1,2,3,4]. inject(0, :+) #10

Dr inż. Stanisław Polak 73

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Metoda zip()

Nie

1 a = [1,2,3,4]2 b = [5,6,7,8]3 wynik =[]4 0.upto(a.length -1).each do |i|5 wynik << [a[i], b[i]]6 end7 wynik #[[1, 5], [2, 6], [3, 7], [4, 8]]

Tak

1 a = [1,2,3,4]2 b = [5,6,7,8]3 wynik = a.zip(b) #[[1, 5], [2, 6], [3, 7], [4, 8]]

Dr inż. Stanisław Polak 74

Notatki

Notatki

Page 35: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Wybrane metody do tworzenia iteratorów

1 [1,2,3]. permutation (2).to_a2 => [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]3 [1,2,3]. permutation.to_a4 => [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]5 ## ############################6 [1,2,3]. combination (2).to_a7 => [[1, 2], [1, 3], [2, 3]]8 ## ############################9 [0,1,2,3]. group_by {|x| x%2}

10 => {0=>[0, 2], 1=>[1, 3]}11 [0,0,0,1,1,2]. group_by {|x| x}.map {|k,v| v}12 => [[0, 0, 0], [1, 1], [2]]

Dr inż. Stanisław Polak 75

Język Ruby Programowanie funkcyjne Funkcje wyższego rzędu

Przykład użycia

1 (1.. Float :: INFINITY).lazy.select { |x| (x**2 % 5).zero? }.take (10).inject (:+)2 => 275

Dr inż. Stanisław Polak 76

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 36: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość

Definiowanie klas i tworzenie obiektów

1 class Zwierze2 end34 puts Zwierze.class #Wypisze: Class5 zwierze = Zwierze.new6 p zwierze #Wypisze: #<Zwierze :0 x000000009c17d8 >

Dr inż. Stanisław Polak 78

Język Ruby Obiektowość Metody

Metody

1 class Zwierze2 @obiekt_self = self3 ## #################################4 ## #### Metoda instancyjna #########5 ## #################################6 def wypisz7 printf "%s %s\n", self, self.class8 end9 ## #################################

10 ## ####### Metoda klasowa ##########11 ## #################################12 def Zwierze.wypisz13 #def self.wypisz14 printf "%s %s %s %s\n", self , self.class , @obiekt_self , @obiekt_self.class15 end16 end17 ## #################################18 z=Zwierze.new19 z.wypisz #Wypisze: #<Zwierze :0 x00000002142d58 > Zwierze20 # To co powyżej jest równoważne z.send(’wypisz’)21 Zwierze.wypisz #Wypisze: Zwierze Class Zwierze Class22 # To co powyżej jest równoważne Zwierze.send(’wypisz’)

Dr inż. Stanisław Polak 79

Notatki

Notatki

Page 37: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Metody

Metoda initialize()

1 class Zwierze2 def initialize(nazwa)3 puts nazwa4 end5 end67 zwierze = Zwierze.new(’Pies’) #Wypisze: Pies

Dr inż. Stanisław Polak 80

Język Ruby Obiektowość Metody

Dostęp do metody klasowej z wnętrza metody instancyjnej

1 class Zwierze2 def metodaInstancyjna3 puts "Jestem metodą instancyjną"4 self.class.metodaKlasowa5 end67 def self.metodaKlasowa8 puts "Jestem metodą klasową"9 end

10 end11 ## ############################12 z = Zwierze.new13 z.metodaKlasowa #Błąd wykonania : undefined method ‘metodaKlasowa ’ ...14 ## ############################15 z.metodaInstancyjna # Wypisze:16 # Jestem metodą instancyjn ą17 # Jestem metodą klasową

Dr inż. Stanisław Polak 81

Notatki

Notatki

Page 38: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Metody

Dziedziczenie

1 class Zwierze #Klasą bazową jest Object2 def initialize3 puts ’Konstruktor Zwierze ’4 end5 end6 ## ###########################7 p Zwierze.superclass #Wypisze: Object8 p Zwierze.superclass.superclass #Wypisze:

BasicObject9 p Zwierze.superclass.superclass.superclass #Wypisze:

nil

10 class Pies < Zwierze11 def initialize12 super13 puts "Konstruktor Pies"14 end15 end16 ## ###########################17 Pies.new #Wypisze:18 # Konstruktor Zwierze19 # Konstruktor Pies

Hierarchia dziedziczenia w Ruby ­ 1.9 Hierarchia dziedziczenia w Ruby ¬ 1.8

Zwierze

Object

BasicObject

Zwierze

Object

Dr inż. Stanisław Polak 82

Język Ruby Obiektowość Atrybuty

AtrybutyInstancyjne

1 class Zwierze2 @ilosc = 134 def wypisz_ilosc5 p @ilosc #Wbrew pozorom , wartością atrybutu ’

@ilosc ’ nie jest 16 end78 def self.wypisz_ilosc9 p @ilosc

10 end1112 # attr writer :gatunek13 def gatunek=(g)14 @gatunek = g15 end1617 # attr reader :gatunek18 def gatunek19 @gatunek20 end2122 attr accessor :wiek # attr_accessor ⇔ attr_reader

∪ attr_writer23 end

24 z = Zwierze.new25 z.wypisz_ilosc #Wypisze: nil26 Zwierze.wypisz_ilosc #Wypisze: 127 puts z.ilosc # ... undefined method ‘ilosc ’ for #<

Zwierze :0 x000000017923d0 > ( NoMethodError )28 puts z.@ilosc # ... syntax error , unexpected tIVAR ,

expecting ’(’29 puts @z.ilosc # ... undefined method ‘ilosc ’ for nil:

NilClass ( NoMethodError )30 z.gatunek = "Ssak"31 puts z.gatunek # Wypisze: "Ssak"32 z.wiek = 1033 puts z.wiek # Wypisze: 10

Dr inż. Stanisław Polak 83

Notatki

Notatki

Page 39: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Atrybuty

AtrybutyKlasowe

1 class Zwierze2 @@ilosc = 034 def initialize5 @@ilosc += 16 end78 def ilosc # metoda instancyjna9 @@ilosc

10 end1112 def self.ilosc # metoda klasowa13 @@ilosc14 end15 end16 ## #######################17 puts Zwierze.ilosc #Wypisze: 018 ## #######################19 class Pies < Zwierze20 @@ilosc = 1021 end22 ## #######################23 puts Pies.ilosc #Wypisze: 1024 puts Zwierze.ilosc #Wypisze: 1025 pies = Pies.new26 puts pies.ilosc #Wypisze: 1127 puts Pies.ilosc #Wypisze: 1128 puts Zwierze.ilosc #Wypisze: 11

Dr inż. Stanisław Polak 84

Język Ruby Obiektowość Atrybuty

Atrybuty klasowe, a atrybuty instancyjne klasy

Atrybut klasowy

1 class Zwierze2 # ’@@ilosc ’ jest atrybutem klasowym dzielonym przez klasę ’

Zwierze ’ i każdą z jej podklas3 # Kiedy tworzysz instancję klasy ’Zwierze ’ lub jej podklasy ,

tj. ’Pies ’,4 # to wartość zmiennej ’ilosc ’ zwiększa się5 @@ilosc = 067 def initialize8 self.class.ilosc += 1 #Wywołanie metod ’self.ilosc=’ oraz

’self.ilosc ’9 end

1011 def self.ilosc12 @@ilosc13 end14 def self.ilosc =( wartosc)15 @@ilosc = wartosc16 end17 end1819 class Pies < Zwierze20 end2122 8.times { Zwierze.new }23 4.times { Pies.new }2425 p Zwierze.ilosc #Wypisze: 1226 p Pies.ilosc #Wypisze: 12

Atrybut instancyjny klasy

1 class Zwierze2 # ’@ilosc ’ jest atrybutem instancyjnym (wyłącznie) klasy ’

Zwierze ’3 # Wartość zmiennej ’ilosc ’ ulega zwiększeniu , tylko wtedy

gdy tworzysz instancję klasy ’Zwierze ’ (nie podklasy ,tj. Pies)

4 @ilosc = 056 def initialize7 self.class.ilosc += 1 #Wywołanie metod ’self.ilosc=’ oraz

’self.ilosc ’8 end9

10 def self.ilosc11 @ilosc12 end13 def self.ilosc=( wartosc)14 @ilosc = wartosc15 end16 end1718 class Pies < Zwierze19 @ilosc = 020 end2122 8.times { Zwierze.new }23 4.times { Pies.new }2425 p Zwierze.ilosc #Wypisze: 826 p Pies.ilosc #Wypisze: 4

Dr inż. Stanisław Polak 85

Notatki

Notatki

Page 40: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Moduły

Moduły

1 module Math2 PI = 3.141592653589793 def Math.sqrt(x)4 # ..5 end6 ...7 end8 ## ########################9 Math.sqrt(2) # => 1.4142135623731

10 Math::sqrt(2) # => 1.414213562373111 Math::PI # => 3.1415926535897912 ## ########################13 module Brzeczyk14 def dzwon15 puts "BZZZZ!BZZZZ!BZZZZ!"16 end17 end18 ## ########################19 class Czasomierz20 def podaj_czas21 puts Time.now22 end23 end24 ## ########################25 class Budzik < Czasomierz26 include Brzeczyk27 end28 ## ########################29 b = Budzik.new30 b.podaj_czas # Sun Aug 05 17:24:08 +0200 200731 b.dzwon # BZZZZ!BZZZZ!BZZZZ!32 Budzik.dzwon # undefined method ‘dzwon ’ for Budzik:

Class ( NoMethodError )

1 class Budzik < Czasomierz2 extend Brzeczyk3 end4 ## ########################5 b = Budzik.new6 b.podaj_czas # Sun Aug 05 17:24:08 +0200 20077 b.dzwon # undefined method ‘dzwon ’ for #<Budzik :0

x0000000242c0c8 > ( NoMethodError )8 Budzik.dzwon #BZZZZ!BZZZZ!BZZZZ!9 zegarek = Czasomierz.new

10 zegarek.extend(Brzeczyk)11 zegarek.dzwon # BZZZZ!BZZZZ!BZZZZ!

Dr inż. Stanisław Polak 86

Język Ruby Obiektowość Moduły

Metody klas oraz modułówSterowanie kolejnością wykonywania

1 module Brzeczyk2 def podaj_czas3 puts "Brzeczyk: " + Time.now.to_s4 super5 end6 end7 ## ########################8 class Czasomierz9 def podaj_czas

10 puts "Czasomierz: " + Time.now.to_s11 end12 end13 ## ########################1415 class Budzik < Czasomierz16 include Brzeczyk17 def podaj_czas18 puts "Budzik: " + Time.now.to_s19 super20 end21 end2223 Budzik.new.podaj_czas

Na wyjściuBudzik: 2014-01-31 13:29:48 +0100Brzeczyk: 2014-01-31 13:29:48 +0100Czasomierz: 2014-01-31 13:29:48 +0100

1 module Brzeczyk2 def podaj_czas3 puts "Brzeczyk: " + Time.now.to_s4 super5 end6 end7 ## ########################8 class Czasomierz9 def podaj_czas

10 puts "Czasomierz: " + Time.now.to_s11 end12 end13 ## ########################1415 class Budzik < Czasomierz16 prepend Brzeczyk #Dostępne w Ruby >= 2.017 def podaj_czas18 puts "Budzik: " + Time.now.to_s19 super20 end21 end2223 Budzik.new.podaj_czas

Na wyjściuBrzeczyk: 2014-01-31 13:31:19 +0100Budzik: 2014-01-31 13:31:19 +0100Czasomierz: 2014-01-31 13:31:19 +0100

Dr inż. Stanisław Polak 87

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 41: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Moduły

Atrybuty instancyjne oraz klasowe modułów

1 module Brzeczyk2 @czas1 = 13 @@czas2 = 245 def self.czas16 @czas17 end89 def self.czas2

10 @@czas211 end12 end13 ## #################14 class Czasomierz15 include Brzeczyk1617 def self.czas118 @czas119 end2021 def self.czas222 @@czas223 end2425 def self.czas2=(czas)26 @@czas2=czas27 end28 end29 ## #################30 p Brzeczyk.czas1 # Wypisze: 131 p Czasomierz.czas1 # Wypisze: nil32 p Brzeczyk.czas2 # Wypisze: 233 p Czasomierz.czas2 # Wypisze: 234 Czasomierz.czas2 = 335 p Brzeczyk.czas2 # Wypisze: 336 p Czasomierz.czas2 # Wypisze: 3

1 module Brzeczyk2 @czas1 = 13 @@czas2 = 245 def self.czas1 # Tutaj ’self ’ oznacza moduł, więc

odbiorcą komunikatu "czas1" będzie tylkomoduł

6 @czas17 end89 def self.czas2

10 @@czas211 end12 end13 ## #################14 class Czasomierz15 include Brzeczyk16 extend Brzeczyk17 end18 ## #################19 p Czasomierz.czas1 # Wyjątek: undefined method ‘

czas1 ’ for Czasomierz :Class20 p Czasomierz.czas2 # Wyjątek: undefined method ‘

czas2 ’ for Czasomierz :Class

Dr inż. Stanisław Polak 88

Język Ruby Obiektowość Inne zagadnienia

Sprawdzanie typu obiektu

1 module Man2 end34 module Woman5 end67 class Person8 include Man9 end

1011 class Player < Person12 include Woman13 end1415 p = Player.new16 p.kind of? Player #true17 p.kind of? Person #true18 p.kind of? Man #true19 p.kind of? Woman #true20 #kind_of? <=> is_a?2122 p.instance of? Player #true23 p.instance of? Person #false24 p.instance of? Man #false25 p.instance of? Woman #false

Dr inż. Stanisław Polak 89

Notatki

Notatki

Page 42: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Inne zagadnienia

Obiekt „main”

1 def funkcja2 puts "Jestem metodą obiektu ’main’"3 end45 class Klasa6 def metoda7 puts "Jestem metodą obiektu ’Klasa’"8 funkcja ()9 end

10 end1112 puts self #Wypisze: main13 puts self.class #Wypisze: Object1415 o=Klasa.new16 o.metoda #Wypisze: Jestem metodą obiektu ’Klasa ’17 # Jestem metodą obiektu ’main ’

Dr inż. Stanisław Polak 90

Język Ruby Obiektowość Inne zagadnienia

Przeciążanie operatorów

1 class Liczba2 def initialize(a)3 @a = a4 end5 ## #############6 def +(b)7 @a + b8 end9 ## #############

10 def -@11 puts "zanegowałeś liczbę"12 end13 end14 liczba = Liczba.new(1)15 puts liczba +416 -liczba

Na wyjściu

5zanegowałeś liczbę

Dr inż. Stanisław Polak 91

Notatki

Notatki

Page 43: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obiektowość Inne zagadnienia

Kontrola dostępu1 class Test2 public # każda metoda (poza initialize (), która jest prywatna) jest domyślnie publiczna3 def pub_met14 end56 private # metoda prywatna7 def priv_met18 end9

10 protected # wymienione niżej metody są chronione11 def prot_met112 end1314 def prot_met215 end16 end

1 class Test2 def pub_met13 end45 def priv_met16 end78 def prot_met19 end

1011 public :pub_met112 private :priv_met113 protected :prot_met114 end

Dr inż. Stanisław Polak 92

Język Ruby Obiektowość Inne zagadnienia

Kontrola dostępuPrzykład użycia

1 class Foo2 def a3 end45 # Wywołanie ’a()’ z jawnym ’self ’ jako odbiorcą6 def b7 self.a8 end9

10 # Wywołanie metody ’a()’ z niejawnym ’self ’ jako odbiorcą11 def c12 a13 end1415 publicprotectedprivate :a16 end17 ## #####################################18 class Foo1 < Foo19 end20 ## #####################################21 def safe_send(receiver , method , message)22 # Nie można używać ’send () ’, ponieważ omija zasady widoczności23 eval "receiver .#{ method}"24 rescue => e25 puts "#{ message }: #{e}"26 else27 puts "#{ message }: wywołanie metody powiodło się"28 end29 ## #####################################30 foo = Foo.new31 foo1 = Foo1.new32 safe_send(foo , :a, "jawny odbiorca ")33 safe_send(foo , :b, "jawny odbiorca ’self’ ")34 safe_send(foo , :c, "niejawny odbiorca ’self’")35 safe_send(foo1 , :a, "jawny odbiorca ")36 safe_send(foo1 , :b, "jawny odbiorca ’self’ ")37 safe_send(foo1 , :c, "niejawny odbiorca ’self’")

skrypt.rb

1 $ ruby skrypt.rb2 jawny odbiorca : wywołanie metody powiodło się3 jawny odbiorca ’self’ : wywołanie metody powiodło się4 niejawny odbiorca ’self’: wywołanie metody powiodło się5 jawny odbiorca : wywołanie metody powiodło się6 jawny odbiorca ’self’ : wywołanie metody powiodło się7 niejawny odbiorca ’self’: wywołanie metody powiodło się

1 $ ruby skrypt.rb2 jawny odbiorca : protected method ‘a’ called for #<Foo:0

x000000028a0960 >3 jawny odbiorca ’self’ : wywołanie metody powiodło się4 niejawny odbiorca ’self’: wywołanie metody powiodło się5 jawny odbiorca : protected method ‘a’ called for #<Foo1 :0

x000000028a0938 >6 jawny odbiorca ’self’ : wywołanie metody powiodło się7 niejawny odbiorca ’self’: wywołanie metody powiodło się

1 $ ruby skrypt.rb2 jawny odbiorca : private method ‘a’ called for #<Foo:0

x000000021b4840 >3 jawny odbiorca ’self’ : private method ‘a’ called for #<Foo :0

x000000021b4840 >4 niejawny odbiorca ’self’: wywołanie metody powiodło się5 jawny odbiorca : private method ‘a’ called for #<Foo1:0

x000000021b4818 >6 jawny odbiorca ’self’ : private method ‘a’ called for #<Foo1 :0

x000000021b4818 >7 niejawny odbiorca ’self’: wywołanie metody powiodło się

Dr inż. Stanisław Polak 93

Notatki

Notatki

Page 44: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW

Model klient-serwerUsługa WWW

Serwer WWW

Adres IP

ProtokółPort

Przeglądarka WWW

Dr inż. Stanisław Polak 94

Język Ruby Obsługa WWW

Wybrane komendy (metody) protokołu HTTP

Komenda „GET”URL żądania:http://www.icsr.agh.edu.pl/index.html

1 GET /index.html HTTP /1.12 Host: www.icsr.agh.edu.pl3

Żądanie

1 HTTP /1.1 200 OK2 Date: Mon , 09 Aug 2013 17:02:08 GMT3 Server: Apache /2.4.4 (UNIX)4 Content -Length: 17765 Content -Type: text/html; charset=utf -867 <!DOCTYPE html>8 <html>9 ...

10 </html>

Odpowiedź

Komenda „POST”URL żądania: http://www.icsr.agh.edu.pl/cgi-bin/search.cgi

1 POST /cgi -bin/search.cgi HTTP /1.12 Host: www.icsr.agh.edu.pl3 Content -Length: 4645 query=alpha+complex&casesens=false&cmd=submit

Żądanie

1 HTTP /1.1 200 OK2 Date: Mon , 09 Aug 2013 17:02:20 GMT3 Server: Apache /2.4.4 (UNIX)4 Content -Length: 17765 Content -Type: text/html; charset=utf -86 Connection: close78 <!DOCTYPE html>9 <html>

10 ...11 </html>

Odpowiedź

Dr inż. Stanisław Polak 95

Notatki

Notatki

Page 45: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW

Wysyłanie danych z formularza HTML

Zatwierdzanie danych 7−→ kodowanie 7−→ wysyłanie do serwera WWW

1 <form method ="..." enctype ="..." action="...">

2 ...3 </form>

I GETI POST

I application/x-www-form-urlencodedI multipart/form-data

Dr inż. Stanisław Polak 96

Język Ruby Obsługa WWW

Kodowanie „application/x-www-form-urlencoded”Przykład

1 <form action="http :// www.serwer.com/script">2 Login: <input name="login" type="TEXT"><br>3 Password: <input name="password" type="PASSWORD">4 </form>

Dokument HTML

Login: Jan

Password: Kowalski (Nowak)

1 login=Jan&password=Kowalski +%28 Nowak %29

Zakodowane dane

Dr inż. Stanisław Polak 97

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 46: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW

Kodowanie „multipart/form-data”Przykład

1 <form action="..." method="POST" enctype="multipart/form -data">2 <input name="login" type="TEXT">3 <input name="password" type="PASSWORD">4 <input name="file" type="FILE" accept="image/jpeg ,image/gif">5 </form>

Jan

Kowalski (Nowak)

image.jpg

1 POST /skrypt HTTP /1.02 Content -Length: 7753 Content -Type: multipart/form -data; boundary =------------------------815276501818664599101790669245 --------------------------81527650181866459910179066926 Content -Disposition: form -data; name="login"78 Jan9 --------------------------8152765018186645991017906692

10 Content -Disposition: form -data; name="password"1112 Kowalski (Nowak)13 --------------------------815276501818664599101790669214 Content -Disposition: form -data; name="file"; filename="image.jpg"15 Content -Type: image/jpeg16 Content -Transfer -Encoding: binary1718 The content of ’image.jpg’19 --------------------------8152765018186645991017906692

Dr inż. Stanisław Polak 98

Język Ruby Obsługa WWW Interfejs Rack

Użycie „Rack”Przykład 1

1 #!/ usr/bin/env ruby2 require ’rack’34 class HelloWorld5 def call(env)6 sleep (10) #uśpij program na 10 sekund7 return [200, {}, ["Hello world!"]]8 end9 end

1011 Rack:: Handler :: WEBrick.run(12 HelloWorld.new ,13 :Port => 900014 )

helloworld.rb

1 $ chmod 755 ./ helloworld.rb2 $ ./ helloworld.rb3 [2014 -04 -14 10:43:16] INFO WEBrick 1.3.14 [2014 -04 -14 10:43:16] INFO ruby 2.1.1 (2014 -02 -24)

[x86_64 -linux]5 [2014 -04 -14 10:43:16] INFO WEBrick :: HTTPServer#

start: pid =9026 port =90006 localhost - - [14/ Apr /2014:10:44:04 CEST] "GET /

HTTP /1.1" 200 127 - -> /

1 $ curl localhost :90002 Hello world!

Dr inż. Stanisław Polak 100

Notatki

Notatki

Page 47: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW Interfejs Rack

Użycie „Rack”Przykład 2

1 class HelloWorld2 def call(env)3 return [4 200,5 {’Content-Type’ => ’text/html’},6 ["Hello world!"]7 ]8 end9 end

1011 run HelloWorld.new

config.ru

1 $ rackup # ⇐⇒ rackup config.ru2 ...3 * Listening on tcp ://0.0.0.0:92924 $ rackup -p 13375 ...6 * Listening on tcp ://0.0.0.0:1337

1 $ curl localhost :92922 Hello world!

Dr inż. Stanisław Polak 101

Język Ruby Obsługa WWW Interfejs Rack

Parametr ’env’

1 class HelloWorld2 def call(env)3 odpowiedź=env.map do |klucz ,wartość|4 klucz.to_s+"="+wartość.to_s+"<br>"5 end6 return [7 200,8 {’Content -Type’ => ’text/html;charset=

utf -8’},9 odpowiedź

10 ]11 end12 end

helloworld.rb

Dr inż. Stanisław Polak 102

Notatki

Notatki

Page 48: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW Interfejs Rack

Obsługa formularzy HTML

1 <form action="http :// localhost :9292/">2 <input type="TEXT" name="a" value="ą" />3 <input type="TEXT" name="b" value="(" />4 <input type="TEXT" name="a" value="1" />5 <input type="SUBMIT">6 </form>

1 class HelloWorld2 def call(env)3 odpowiedź = ""4 # Odczytywanie danych otrzymanych od przeglądarki5 odpowiedź << env[’QUERY STRING’] #Dane

otrzymane (metodą GET) od przeglądarki6 odpowiedź << env[’rack.input’].read #Dane

otrzymane (metodą POST) od przeglądarki78 #Wysyłanie odpowiedzi do przeglądarki9 return [

10 200,11 {’Content -Type’ => ’text/html’},12 [odpowiedź]13 ]14 end15 end

helloworld.rb

Dr inż. Stanisław Polak 103

Język Ruby Obsługa WWW Interfejs Rack

Obsługa formularzy HTMLObiekt Rack::Request

1 <form action="http :// localhost :9292/">2 <input type="TEXT" name="a[]" value="ą" />3 <input type="TEXT" name="b" value="(" />4 <input type="TEXT" name="a[]" value="1" />5 <input type="SUBMIT">6 </form>

1 class HelloWorld2 def call(env)3 req = Rack::Request.new(env)4 odpowiedź = [5 "a="+req.params[’a’][0]+"<br>",6 "a="+req.params[’a’][1]+"<br>",7 "b="+req.params[’b’] # zamiast "req.params[’b ’]"

można użyć "req[’b ’]"8 ]9 return [

10 200,11 {’Content -Type’ => ’text/html;charset=

utf -8’},12 odpowiedź13 ]14 end15 end

helloworld.rb

Dr inż. Stanisław Polak 104

Notatki

Notatki

Page 49: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW Interfejs Rack

Obsługa formularzy HTMLObiekt Rack::Response

1 class HelloWorld2 def call(env)3 req = Rack:: Request.new(env)4 res = Rack::Response.new5 res.write("a="+req.params[’a’][0]+"<br >") #Dopisuje podany tekst do ciała odpowiedzi6 res.write("a="+req.params[’a’][1]+"<br >")7 res.write("b="+req.params[’b’])8 res[’Content -Type’] = ’text/html;charset=utf -8’ # Ustawienie nagłówka "Content -type"9 res.status = 200 #zbędne , gdyż jest to domyślny kod statusu

10 res.finish #zwróć odpowiedź w postaci ( trzyelementowej ) tablicy11 end12 end

helloworld.rb

Dr inż. Stanisław Polak 105

Język Ruby Obsługa WWW Interfejs Rack

Tworzenie aplikacji pośredniczącej („Middleware”)

1 # Źródło: http :// code.tutsplus.com/articles/exploring -rack --net -329762 class ToUpper3 # Our class will be initialize with another Rack app4 def initialize(app)5 @app = app6 end78 def call(env)9 # First , call ‘@app ‘

10 status , headers , body = @app.call(env)1112 # Iterate through the body , upcasing each chunk13 upcased_body = body.map { |chunk| chunk.upcase }1415 # Pass our new body on through16 [status , headers , upcased_body]17 end18 end19 ## ###############################################20 class Hello21 def self.call(env)22 [ 200, {"Content -Type" => "text/plain"}, ["Hello from Rack!"] ]23 end24 end25 ## ###############################################26 use ToUpper # Tell Rack to use our newly -minted middleware27 run Hello28 # Odpowiednik : app = ToUpper.new(Hello); run app

config.ru

Dr inż. Stanisław Polak 106

Notatki

Notatki

Page 50: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Język Ruby Obsługa WWW Interfejs Rack

Aplikacja pośredniczącaPrzekazywanie parametrów

1 class ToUpper2 def initialize(app, param, &blok)3 puts app4 puts app.class5 puts ’-’ * 106 puts param7 puts param.class8 puts ’-’ * 109 blok.call(’Napis’)

10 end1112 ...13 end1415 class Hello16 ...17 end1819 # use(middleware, *args, &block)20 use ToUpper, ’Argument’ { |arg| puts arg }21 run Hello

config.ru

Na wyjściu

HelloClass----------ArgumentString----------Napis

Dr inż. Stanisław Polak 107

Język Ruby Obsługa WWW Interfejs Rack

Ogólnodostępne aplikacje pośredniczącePrzykład użycia

1 require ’./ helloworld ’2 require ’rack/contrib ’34 use Rack::Static , :urls => ["/css", "/images"], :root => "

public"5 use Rack:: ContentType , "text/plain"6 use Rack:: BounceFavicon7 use Rack::Reloader , 08 run HelloWorld.new

config.ru

1 <link rel="stylesheet" href="/css/style.css">

Dokument HTML

1 h1 {color: red}

public/css/style.css

Dr inż. Stanisław Polak 108

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 51: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

Framework

I Dostarcza szkieletu do tworzenia aplikacji lub jej wybranych częściI Dostarcza zbioru ogólnych funkcjonalnościI Gotowe komponenty do budowy aplikacji WWWI Ułatwia proces wdrożania nowego pracownikaI Nie jest gotową aplikacją — jest zbiorem kodu i pewnych metod postępowania, dzięki którym

można efektywnie budować aplikacjeI Typowe cechy:

I Odwrócenie sterowaniaI Domyślne zachowanieI RozszerzalnośćI Zamknięta struktura wewnętrzna

I Typowe elementy:I Mechanizm uruchamiania i przetwarzania akcjiI Mechanizm tworzenia logiki biznesowej aplikacjiI Zarządzanie konfiguracjąI Zarządzanie komunikacją z bazą danychI Obsługa formularzyI System szablonówI Obsługa błędówI Mechanizmy bezpieczeństwa, uwierzytelniania i kontroli dostępuI Generatory kodu

Dr inż. Stanisław Polak 109

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

Wzorzec projektowy MVCŚrodowisko WWW

I MVC (ang. Model-View-Controller) —Model-Widok-Kontroler

I Podstawowe komponenty aplikacji:I Model → logika biznesowaI Widok→ logika prezentacjiI Kontroler → logika sterowania

I Bazuje na klasycznym wzorcu MVCI Zalety:

I StandaryzacjaI NiezależnośćI Łatwość modyfikacjiI Szybkość

I Wada: ZłożonośćI Kiedy stosować?

I Złożone aplikacjeI Potrzeba utrzymywania i dostosowywania do

nowych potrzebI Wyznaczenie obszarów kompetencjiI Wielokrotna używalność

Kontroler Widok

Model

Serwer

Klient

żądanie HTTP odpowiedź HTTP

Dr inż. Stanisław Polak 110

Notatki

Notatki

Page 52: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

Wzorzec „Active record”

1 product = Product.new2 product.name = "Komputer"3 product.price = 123.454 product.save()

Dodanie nowego wiersza w tabeli

1 INSERT INTO products (name , price) VALUES (’Komputer’, 123.45);

SQL-owy odpowiednik powyższego kodu

1 b = Product.find (1)

Wyszukiwanie w bazie danych

1 SELECT * FROM products WHERE (products.id = 1)LIMIT 1; -- MySQL lub PostgreSQL

SQL-owy odpowiednik powyższego kodu

Dr inż. Stanisław Polak 111

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

CRUD

Działanie Instrukcja SQLCreate INSERTRead SELECTUpdate UPDATEDelete DELETE

Dr inż. Stanisław Polak 112

Notatki

Notatki

Page 53: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

System szablonów

1 require ’erb’23 class Strona4 attr_accessor :tytul5 attr_accessor :produkty67 def renderuj(sciezka)8 zawartosc = File.read(File.expand_path(sciezka)) # Wczytaj9 # treść

10 #szablonu

11 t = ERB.new(zawartosc)12 t.result(binding) # Dokonaj ewaluacji kodu szablonu13 # znajdującego się w zmiennej ’zawartosc

’,14 # a następnie zwróć wygenerowany

dokument15 # HTML16 # Funkcja ’binding ()’ tworzy obiekt klasy ’Binding ’17 # (domknięcie) - obiekty tej klasy enkapsuluj ą kontekst18 # wykonania (wartość zmiennych , ...) w określonym miejscu19 # kodu oraz zachowują ten kontekst do wykorzystania w20 # przyszłości21 end22 end2324 stronaWWW = Strona.new25 stronaWWW.tytul = ’Tytuł strony ’26 stronaWWW.produkty = %w[Produkt1 Produkt2]27 puts stronaWWW.renderuj(’szablon.html.erb’)

skrypt.rb

1 <html>2 <head>3 <title><%= @tytul %></title >4 </head>5 <body>6 <ul>7 <% for produkt in @produkty %>8 <li><%= produkt %></li>9 <% end %>

10 </ul>11 </body>12 </html>

szablon.html.erb

1 <html>2 <head>3 <title>Tytuł strony </title>4 </head>5 <body>6 <ul>7 <li>Produk1 </li>8 <li>Produkt2 </li>9 </ul>

10 </body>11 </html>

Wynikowy dokument HTML

Dr inż. Stanisław Polak 113

Podstawowe pojęcia związane z tworzeniem aplikacji internetowych

RESTI Representational State Transfer

Zasób GET PUT POST DELETEKolekcja URI ta-kich jak http://przyklad.pl/uzytkownik/

Listuj URI i byćmoże inne szcze-góły członków ko-lekcji.

Zastąp całą kolek-cję inną kolekcją.

Utwórz nowywpis w kolekcji.Nowy URL jestautomatycznieprzydzielany wpi-sowi i zwykle jestzwracany przezoperację.

Usuń całą kolekcję.

Elementy URItakie jak http://przyklad.pl/uzytkownik/13

Pobierz reprezen-tację podanegoczłonka kolek-cji, wyrażoną wokreślonym typiemediów interneto-wych.

Zastąp podanegoczłonka kolekcji lubjeśli nie istnieje,utwórz go.

Traktuj podanegoczłonka jako kolek-cję samą w sobie iutwórz w niej nowywpis.

Usuń podanegoczłonka kolekcji.

Dr inż. Stanisław Polak 114

Notatki

Notatki

Page 54: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

Przykład „Hello World”

1 require ’sinatra ’2 require ’sinatra/reloader ’ if development? # Wymaga gema ’sinatra -contrib ’34 get ’/witaj ’ do5 "Witaj Świecie\n"6 end

skrypt.rb

1 $ ruby skrypt.rb2 [2017 -06 -30 18:17:33] INFO WEBrick 1.3.13 [2017 -06 -30 18:17:33] INFO ruby 2.4.1 (2017 -03 -22) [x86_64 -linux]4 == Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from WEBrick5 [2017 -06 -30 18:17:33] INFO WEBrick :: HTTPServer#start: pid =3521 port =4567

Uruchamianie aplikacji

1 $ curl http :// localhost :4567/ witaj2 Witaj Świecie

Wykonywanie żądania

Dr inż. Stanisław Polak 116

Podstawy języka dziedzinowego „Sinatra”

TrasyDefiniowanie

1 get ’/’ do2 .. wyświetl coś ..3 end45 post ’/’ do6 .. utwórz coś ..7 end89 put ’/’ do

10 .. zastąp coś ..11 end1213 patch ’/’ do14 .. zmodyfikuj coś ..15 end1617 delete ’/’ do18 .. unicestw coś ..19 end20 ...

Dr inż. Stanisław Polak 117

Notatki

Notatki

Page 55: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

TrasyDopasowywanie

1 get ’/witaj ’ do2 "Pierwsza trasa\nhasz ’params ’ zawiera: #{params.inspect }\n"3 end45 get ’/witaj ’ do #Ta trasa nie zostanie (nigdy) dopasowana6 "Druga trasa\nhasz ’params ’ zawiera: #{ params.inspect }\n"7 end89 get ’/witaj/:nazwa’ do

10 "Trzecia trasa\nhasz ’params ’ zawiera: #{params.inspect }\n"11 end

1 $ curl http :// localhost :4567/ witaj2 Pierwsza trasa3 hasz ’params ’ zawiera: {}4 $ curl ’http :// localhost :4567/ witaj?imie=Stanislaw&nazwisko=Polak’5 Pierwsza trasa6 hasz ’params ’ zawiera: {"imie"=>"Stanislaw", "nazwisko"=>"Polak"}7 $ curl http :// localhost :4567/ witaj/Swiecie8 Trzecia trasa9 hasz ’params ’ zawiera: {"splat"=>[], "captures"=>["Swiecie"], "nazwa"=>"Swiecie"}

10 $ curl ’http :// localhost :4567/ witaj/Swiecie?imie=Stanislaw&nazwisko=Polak’11 Trzecia trasa12 hasz ’params ’ zawiera: {"imie"=>"Stanislaw", "nazwisko"=>"Polak", "splat"=>[], "captures"=>["Swiecie"],

"nazwa"=>"Swiecie"}

Dr inż. Stanisław Polak 118

Podstawy języka dziedzinowego „Sinatra”

SzablonUżycie szablonu ERB

1 get ’/witaj ’ do2 erb(:witaj) #Renderuj szablon ’views/witaj.erb ’

3 end

skrypt.rb

1 <%# To jest komentarz %>2 <%# Poniżej jest skryptlet %>3 <% 3. downto (0) do |i| %>4 <%# Poniżej jest wyrażenie %>5 <%= i %>,6 <% end %>7 Start

views/witaj.erb

1 $ curl http :// localhost :4567/ witaj2 3,3 2,4 1,5 0,6 Start

Wykonywanie żądania

Dr inż. Stanisław Polak 120

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 56: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

Szablon „inline”

1 require ’sinatra ’23 get ’/witaj ’ do4 erb(:witaj)

5 end6 __END__78 @@witaj9 <%# To jest komentarz %>

10 <%# Poniżej jest skryptlet %>11 <% 3. downto (0) do |i| %>12 <%# Poniżej jest wyrażenie %>13 <%= i %>,14 <% end %>15 Start

skrypt.rb

Dr inż. Stanisław Polak 121

Podstawy języka dziedzinowego „Sinatra”

Szablon częściowy

1 require ’sinatra ’23 get ’/’ do4 erb(:index)5 end

skrypt.rb

1 <%= erb(:witaj) %>2 <%= erb(: swiecie) %>

views/index.erb

1 Witaj

views/witaj.erb

1 Świecie

views/swiecie.erb

1 $ curl http :// localhost :4567/2 Witaj3 Świecie

Wykonywanie żądania

Dr inż. Stanisław Polak 122

Notatki

Notatki

Page 57: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

Układ

1 <html>2 <head>3 <title>Aplikacja Sinatra </title>4 </head>5 <body>6 <h1>Aplikacja Sinatra </h1>7 <!-- początek wstawki szablonu -->8 <%= yield %>9 <!-- koniec wstawki szablonu -->

10 </body>11 </html>

views/layout.erb

1 <% 3. downto (0) do |i| %>2 <%= i %>,3 <% end %>4 Start

views/witaj.erb

1 $ curl http :// localhost :4567/ witaj2 <html >3 <head >4 <title >Aplikacja Sinatra </title >5 </head >6 <body >7 <h1>Aplikacja Sinatra </h1>8 <!-- początek wstawki szablonu -->9 3,

10 2,11 1,12 0,13 Start1415 <!-- koniec wstawki szablonu -->16 </body >17 </html >

Wykonywanie żądania

Dr inż. Stanisław Polak 123

Podstawy języka dziedzinowego „Sinatra”

Dostęp do zmiennych z poziomu szablonu

1 require ’sinatra ’23 get ’/witaj ’ do4 @tekst1 = "Witaj" #Zmienna instancyjna jest dostępna z poziomu szablonu5 tekst2 = "Świecie" #Zwykła zmienna nie jest dostępna z poziomu szablonu6 erb(:witaj , :locals => {:tekst3 => tekst2 }) #Definiowanie , dla szablonu ’witaj ’, zmiennej lokalnej ’

tekst3 ’7 end

skrypt.rb

1 <%= @tekst1 %> <%= tekst3 %>

views/witaj.erb

1 $ curl http :// localhost :4567/ witaj2 Witaj Świecie

Wykonywanie żądania

Dr inż. Stanisław Polak 124

Notatki

Notatki

Page 58: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

PrzykładPrzetwarzanie zawartości formularza

1 require ’sinatra ’23 get ’/formularz ’ do4 erb :formularz5 end67 post ’/formularz ’ do8 "Pole ’nazwa ’ zawiera napis ’#{params[:nazwa]}’"9 end

skrypt.rb

1 <form action="/formularz" method="post">2 <input type="text" name="nazwa">3 <input type="submit">4 </form>

views/formularz.erb

Dr inż. Stanisław Polak 125

Podstawy języka dziedzinowego „Sinatra”

REST API w Sinatra

1 require ’sinatra ’23 use Rack::MethodOverride45 get ’/formularz ’ do6 erb :formularz7 end89 delete ’/products /:id’ do

10 "Usuwam produkt o id=#{ params[’id ’]}"11 end

skrypt.rb

1 <form method="POST" action="/products /1">2 <input type="hidden" name=" method" value="DELETE">3 <input type="submit">4 </form>

views/formularz.erb

Dr inż. Stanisław Polak 126

Notatki

Notatki

Page 59: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Podstawy języka dziedzinowego „Sinatra”

Trasowanie plików statycznych

1 <!DOCTYPE html>2 <html>3 <head>4 <meta charset="UTF -8">5 <link rel="stylesheet" href="/css/style.css">6 <title>Aplikacja Sinatra </title>7 </head>8 <body>9 <h1>Aplikacja Sinatra </h1>

10 <%= yield %>11 </body>12 </html>

views/layout.erb

1 h1 {color: red}

public/css/style.css

Dr inż. Stanisław Polak 127

Framework Ruby on Rails

Plan prezentacji

Wstęp

Przykład tworzenia aplikacji

Kontroler

Model

Widok

Lokalizacja i umiędzynarodowienie

Uwierzytelnianie i autoryzacja

Dr inż. Stanisław Polak 128

Notatki

Notatki

Page 60: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp

Instalacja Ruby on RailsPrzykład dla Ubuntu

1 # Instalacja ’Node.js ’2 $ sudo apt -get install nodejs3 # Instalacja ’yarn ’4 $ curl -sS https ://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt -key add -5 $ echo "deb https ://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list6 $ sudo apt -get update && sudo apt -get install yarn7 # Instalacja ’Ruby on Rails ’8 $ gem install rails

Instalacja

1 $ gem update rails

Aktualizacja

Dr inż. Stanisław Polak 131

Framework Ruby on Rails Wstęp

Serwer aplikacji „Phusion Passenger” (mod passenger)

I Serwer aplikacji dla Ruby, Python, Node.js oraz MeteorI Obsługuje żądania HTTP, zarządza procesami oraz zasobami, a także umożliwia administrowanie,

monitorowanie i diagnozowanie problemówI Może działać jako samodzielny serwer aplikacji oraz serwer WWWI Posiada możliwość integracji z serwerami WWW: „Apache” oraz „nginx”

Źródło: https://www.phusionpassenger.com/

1 $ gem install passenger2 $ rvmsudo passenger -config validate -install3 $ cd katalog_z_aplikacją_RoR4 $ passenger start --daemonize

Przykład dla Linux-a / macOS-a

Dr inż. Stanisław Polak 132

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 61: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp

Typowe żądanie

Przykładowy adres strony: http://www.przyklad.pl/ students / 1 / edit

Źródło: http://www.sitepoint.com/getting-started-with-mvc/

Dr inż. Stanisław Polak 133

Framework Ruby on Rails Wstęp Konwencje nazewnicze

Konwencje dla tabel bazy danych i modeli

Nazwa tabeli Nazwa (klasy) modelu Nazwa pliku z modelemstudents Student student.rbuniversity employees UniversityEmployee university employee.rb

Tabela łącznikowa: students teachers

id faculty id firstName lastName1 4 Jan Kowalski. . . . . . . . . . . .

Tablica: students

id name. . . . . .4 Informatyki. . . . . .

Tablica: faculties

1 class Student < ApplicationRecord2 ...3 end

app/models/student.rb

Dr inż. Stanisław Polak 134

Notatki

Notatki

Page 62: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp Konwencje nazewnicze

Konwencje dla kontrolerów

1 class StudentsController < ApplicationController23 # http :// www.przyklad.pl/students4 def index5 ...6 end78 # http :// www.przyklad.pl/students /1/ edit9 def edit

10 ...11 end1213 ...14 end

app/controllers/students controller.rb

Dr inż. Stanisław Polak 135

Framework Ruby on Rails Wstęp Konwencje nazewnicze

Konwencje dla widoków

1 <h1>List of students </h1>2 <table >3 ...4 <% @students.each do |student| %>5 <td ><%= student.lastName %></td >6 ...7 <% end %>8 ...9 </table >

app/views/students/index.html.erb

1 <h1>Editing Student </h1 >2 <%= form_with :scope :student , url: student_path(@student),

method: :patch do |f| %>3 ...4 <% end %>

app/views/students/edit.html.erb

1 class StudentsController < ApplicationController23 def index4 ...5 end6 ...7 def edit8 ...9 end

10 ...11 end

app/controllers/students controller.rb

Dr inż. Stanisław Polak 136

Notatki

Notatki

Page 63: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp Konwencje nazewnicze

Przykład zastosowania

Adres strony: http://www.przyklad.pl/students/1/edit

1 class StudentsController < ApplicationController2 ...3 def edit4 ...5 end6 ...7 end

app/controllers/students controller.rb

1 class Student < ApplicationRecord2 ...3 end

app/models/student.rb

id faculty id firstName lastName

1 . . . . . . . . .

Tablica: students

1 <h1>Editing Student </h1 >2 <%= form_with :scope :student , url: student_path(@student), method: :patch do |f| %>3 ...4 <% end %>

app/views/students/edit.html.erb

Dr inż. Stanisław Polak 137

Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń

Program „rails”

1 $ rails2 Usage: rails COMMAND [ARGS]34 The most common rails commands are:5 generate Generate new code (short -cut alias: "g")6 console Start the Rails console (short -cut alias: "c")7 server Start the Rails server (short -cut alias: "s")8 test Run tests (short -cut alias: "t")9 dbconsole Start a console for the database specified in config/database.yml

10 (short -cut alias: "db")11 new Create a new Rails application. "rails new my_app" creates a12 new application called MyApp in "./ my_app"1314 All commands can be run with -h (or --help) for more information.1516 In addition to those commands , there are:17 ...

Dr inż. Stanisław Polak 138

Notatki

Notatki

Page 64: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń

Program „rake”

1 $ rake --tasks2 # rails --tasks # Możliwość dostępna w RoR ­ 5.03 ...4 rake db:create # Create the database from DATABASE_URL or config/database.yml

for the current Rails.env (use db:create:all to create all dbs in the config)5 rake db:drop # Drops the database using DATABASE_URL or the current Rails.env

(use db:drop:all to drop all databases )6 rake db:fixtures:load # Load fixtures into the current environment ’s database7 rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false , SCOPE

=blog)8 rake db:rollback # Rolls the schema back to the previous version (specify steps w

/ STEP=n)9 rake db:schema:dump # Create a db/schema.rb file that can be portably used against

any DB supported by AR10 rake db:schema:load # Load a schema.rb file into the database11 rake db:seed # Load the seed data from db/seeds.rb12 rake db:setup # Create the database , load the schema , and initialize with the

seed data (use db:reset to also drop the db first)13 rake db:structure:dump # Dump the database structure to db/ structure.sql14 rake routes # Print out all defined routes in match order , with names15 rake test # Runs test:units , test:functionals , test: integration together16 ...

Dr inż. Stanisław Polak 139

Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń

Program „bundle”

1 source ’https :// rubygems.org’23 # Bundle edge Rails instead: gem ’rails ’, github: ’rails/rails

’4 gem ’rails ’, ’4.2.5 ’5 # Use sqlite3 as the database for Active Record6 gem ’sqlite3 ’7 # Use SCSS for stylesheets8 gem ’sass -rails ’, ’~> 5.0’9 # Use Uglifier as compressor for JavaScript assets

10 gem ’uglifier ’, ’>= 1.3.0’11 ...

Gemfile

1 GEM2 remote: https :// rubygems.org/3 specs:4 actionmailer (4.2.5)5 actionpack (= 4.2.5)6 actionview (= 4.2.5)7 activejob (= 4.2.5)8 mail (~> 2.5, >= 2.5.4)9 rails -dom -testing (~> 1.0, >= 1.0.5)

10 actionpack (4.2.5)11 ...

Gemfile.lock

1 $ bundle install2 Fetching gem metadata from https :// rubygems.org /...........3 Fetching version metadata from https :// rubygems.org /...4 Fetching dependency metadata from https :// rubygems.org/..5 Resolving dependencies .....6 Using rake 10.4.27 Using i18n 0.7.08 Using json 1.8.39 Using minitest 5.8.3

10 Using thread_safe 0.3.511 Using builder 3.2.212 Using erubis 2.7.013 Using mini_portile2 2.0.014 Using rack 1.6.415 ...16 Using web -console 2.2.117 Using turbolinks 2.5.318 Bundle complete! 12 Gemfile dependencies , 54 gems now

installed.19 Use ‘bundle show [gemname]‘ to see where a bundled gem is

installed.

Instalowanie zależności

Dr inż. Stanisław Polak 140

Notatki

Notatki

Page 65: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń

Program „spring”1 $ spring --help2 Version: 1.7.234 Usage: spring COMMAND [ARGS]56 Commands for spring itself:78 binstub Generate spring based binstubs. Use --all to generate a binstub for all known commands. Use --

remove to revert.9 help Print available commands.

10 server Explicitly start a Spring server in the foreground11 status Show current status.12 stop Stop all spring processes for this project.1314 Commands for your application:1516 rails Run a rails command. The following sub commands will use spring: console , runner , generate ,

destroy , test.17 rake Runs the rake command

Dr inż. Stanisław Polak 141

Framework Ruby on Rails Wstęp Testy

TestowanieStruktura katalogów

1 $ ls test2 application_system_test_case.rb fixtures integration models test_helper.rb3 controllers helpers mailers system

Dr inż. Stanisław Polak 144

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 66: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Przykład tworzenia aplikacji

Pierwsza aplikacjaZałożenia

I Wyświetlamy dane użytkowników: imię oraz nazwiskoI Dane są umieszczone w kodzie źródłowym kontrolera

Dr inż. Stanisław Polak 145

Framework Ruby on Rails Przykład tworzenia aplikacji

Tworzenie szkieletu aplikacjiOgólna struktura katalogu z kodem aplikacji

1 $ rails new firstApp

firstApp

app

bin

config

config.ru

db

Gemfile

Gemfile.lock

lib

log

package.json

public

Rakefile

README.rdoc

storage

test

tmp

vendor

Dr inż. Stanisław Polak 146

Notatki

Notatki

Page 67: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Przykład tworzenia aplikacji

Tworzenie aplikacji

1 $ cd firstApp2 $ bin/rails generate controller users index3 create app/controllers/users_controller.rb4 route get ’users/index’5 invoke erb6 create app/views/users7 create app/views/users/index.html.erb8 invoke test_unit9 create test/controllers/users_controller_test.rb

10 invoke helper11 create app/helpers/users_helper.rb12 invoke test_unit13 invoke assets14 invoke coffee15 create app/assets/javascripts/users.coffee16 invoke scss17 create app/assets/stylesheets/users.scss18 $ bin/rails server19 => Booting Puma20 => Rails 5.0.0 application starting in development on http ://

localhost :300021 => Run ‘rails server -h‘ for more startup options22 Puma starting in single mode ...23 * Version 3.4.0 (ruby 2.3.1 - p112), codename: Owl Bowl Brawl24 * Min threads: 5, max threads: 525 * Environment: development26 * Listening on tcp:// localhost :300027 Use Ctrl -C to stop

1 class UsersController < ApplicationController2 def index3 @@user1 = ’Joanna Wiśniewska ’4 @user2 = ’Jan Kowalski ’5 user3 = ’Anna Nowak’6 end7 end

app/controllers/users controller.rb

1 <h1>Lista użytkowników</h1>2 <% if defined? @@user1 %>3 <%= @@user1 %>4 <% end %>56 <% if defined? @user2 %>7 <%= @user2 %>8 <% end %>9

10 <% if defined? user3 %>11 <%= user3 %>12 <% end %>

app/views/users/in-dex.html.erb

Dr inż. Stanisław Polak 147

Framework Ruby on Rails Kontroler

Parametry

1 class UsersController < ApplicationController2 ...34 def show56 # Dla URL ’http :// localhost :3000/ users /1’,7 # tablica ’params ’ zawiera: {" action "=>" show", " controller "=>" users", "id "= >"1"}8 id = params [:id] #19 nazwa_kontrolera = controller_name # ’users ’

10 nazwa_akcji = action_name # ’show ’11 end12 end

app/controllers/users controller.rb

Dr inż. Stanisław Polak 148

Notatki

Notatki

Page 68: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler

Tworzenie odpowiedzi HTTP

I render

I redirect to

I head

1 class UsersController < ApplicationController2 def index3 # Renderowanie niczego4 render nothing: true #Kod statusu: 2005 render nothing: true , status: 404 #Kod statusu: 4046 # Renderowanie szablonu dla akcji7 render "edit"8 render :edit9 # Renderowanie szablonu dla akcji z innego kontrolera

10 render ’products/show’11 render :template => ’products/show’12 # Renderowanie dowolnego pliku13 render :file => "/u/apps/warehouse_app/current/app/views/products/show"14 # Renderowanie typu "inline"15 render :inline => "<% users.each do |u| %><p><%= u.nazwisko %><p><% end %>"16 render :inline => "xml.p {’Horrid coding practice!’}", :type => :builder17 render :plain => "OK" # Renderowanie tekstu , typ zawartości: text/plain18 render :html => "OK" # Renderowanie tekstu , typ zawartości: text/html19 render :body => "OK" # Renderowanie tekstu , typ zawartości nie jest ustawiany20 render :json => @user # Renderowanie JSON21 render :xml => @user # Renderowanie XML22 render :js => "alert(’Hello Rails ’);" # Renderowanie JS23 end24 end

app/controllers/users controller.rb

Dr inż. Stanisław Polak 149

Framework Ruby on Rails Kontroler

Filtry

TypyI wstępny — before actionI końcowy — after actionI okalający — around action

ArgumentyI Odniesienie do metody (symbol)I Klasa zewnętrznaI Metoda inline (proc)

1 class UsersController < ApplicationController2 before_action :set_user , only: [:show , :edit , :update , :destroy]3 ...4 # Use callbacks to share common setup or constraints between actions.5 def set_user6 @user = User.find(params [:id])7 end8 end

Kontroler

Dr inż. Stanisław Polak 150

Notatki

Notatki

Page 69: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler

Przykłady użycia filtra okalającego

1 class ApplicationController < Application23 around_action :catch_exceptions45 private67 def catch_exceptions8 yield9 rescue => exception

10 logger.debug "Caught exception! #{ exception}"11 raise12 end1314 end

1 around_action do |controller , action|23 #Plik logów - log/ development .log4 logger.debug "before #{ controller.action_name}"5 action.call6 logger.debug "after #{ controller.action_name}"7 end

Dr inż. Stanisław Polak 151

Framework Ruby on Rails Kontroler

Sesja

I CookieStoreI CacheStoreI ActiveRecordStoreI MemCacheStore

1 class UsersController < ApplicationController2 def index3 if session.has_key ?(: licznik)4 session [: licznik] += 15 else6 session[:licznik] = 17 end8 if session [: licznik] > 39 session[:licznik] = nil

10 end11 end12 end

app/controllers/users controller.rb

1 <%= session[:licznik] %>

app/views/users/index.html.erb

Wynik dla kolejnych żądań123

1

Dr inż. Stanisław Polak 152

Notatki

Notatki

Page 70: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler

Flash

1 class UsersController < ApplicationController2 def index3 if session.has_key ?(: licznik)4 session [: licznik] += 15 else6 session [: licznik] = 17 end8 if session [: licznik] == 19 flash[:komunikat] = "Witaj"

10 elsif session [: licznik] > 311 session [: licznik] = nil12 end13 end14 end

app/controllers/users controller.rb

1 <%= session [: licznik] %>2 <%= flash[:komunikat] %>

app/views/users/index.html.erb

Wynik dla kolejnych żądań

1 Witaj2 Witaj3

1 Witaj

Dr inż. Stanisław Polak 153

Framework Ruby on Rails Kontroler

Ciasteczka

1 class UsersController < ApplicationController2 def index3 if cookies.has_key ?(: licznik)4 cookies [: licznik] = cookies [: licznik ].to_i + 15 else6 cookies [: licznik] = 17 end8 if cookies [: licznik] > 39 cookies.delete (: licznik)

10 end11 end12 end

app/controllers/users controller.rb

1 <%= cookies [: licznik] %>

app/views/users/index.html.erb

Wynik dla kolejnych żądań

123

1

Dr inż. Stanisław Polak 154

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 71: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler

Uwierzytelnianie HTTP

Podstawowe

1 class UsersController < ApplicationController2 http_basic_authenticate_with name: "abc", password

: "hasło", except: :index34 def index5 ...6 end78 def show9 ...

10 end11 end

Przez skrót

1 class UsersController < ApplicationController2 USERS = { "abc" => "hasło" }34 before_action :authenticate56 private78 def authenticate9 authenticate_or_request_with_http_digest do |

username|10 USERS[username]11 end12 end13 end

Dr inż. Stanisław Polak 155

Framework Ruby on Rails Kontroler

RoutingCRUD, typy żądań i akcje

1 Users:: Application.routes.draw do2 resources :users3 end

config/routes.rb

ŻądanieHTTP

Ścieżka Akcja Cel użycia

GET /users index wyświetlenie listy wszystkich użytkownikówGET /users/new new zwrócenie formularza HTML do tworzenia użytkow-

nikaPOST /users create utworzenie nowego użytkownikaGET /users/:id show wyświetlenie konkretnego użytkownikaGET /users/:id/edit edit zwrócenie formularza HTML do edycji użytkownikaPATCH /PUT

/users/:id update aktualizacja konkretnego użytkownika

DELETE /users/:id destroy usunięcie konkretnego użytkownika

Dr inż. Stanisław Polak 156

Notatki

Notatki

Page 72: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler

RoutingAdresy URL i ścieżki dostępu

Pomocnik Wynikusers path /usersusers url http://localhost:3000/usersnew user path /users/newedit user path(10) /users/10/edituser path(10) /users/10

Dr inż. Stanisław Polak 157

Framework Ruby on Rails Kontroler Testy funkcjonalne

Przykładowa aplikacjaGenerowanie szkieletu aplikacji oraz konfiguracja

1 $ rails new secondApp2 $ cd secondApp3 $ vim config/routes.rb

1 Rails.application.routes.draw do2 resources :users3 end

config/routes.rb

Dr inż. Stanisław Polak 160

Notatki

Notatki

Page 73: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Kontroler Testy funkcjonalne

Przykładowa aplikacjaKontroler oraz widok

1 $ bin/rails generate controller users2 $ vim app/controllers/users_controller.rb3 $ vim app/views/users/index.html.erb

1 class UsersController < ApplicationController2 @@user1 = nil3 @@user2 = ’Anna Nowak’4 ## #############################5 def index6 @user1 = @@user17 @user2 = @@user28 end9

10 def new11 @@user1 = ’Jan Kowalski ’12 redirect_to users_path13 end14 end

app/controllers/users controller.rb

1 <ul>2 <% if defined? @user1 %>3 <li ><%= @user1 %>4 <% end %>5 <% if defined? @user2 %>6 <li ><%= @user2 %>7 <% end %>8 </ul >

app/views/users/index.html.erb

Dr inż. Stanisław Polak 161

Framework Ruby on Rails Kontroler Testy funkcjonalne

Przykładowe test funkcjonalne dla kontrolera

1 $ vim test/controllers/users_controller_test.rb

2 $ bin/rails test test/controllers/users_controller_test.rb

3 Running via Spring preloader in process454

4 Run options: --seed 2783356 # Running:78 .9

10 Finished in 0.781415s, 1.2797 runs/s,14.0770 assertions/s.

11 1 runs , 11 assertions , 0 failures , 0errors , 0 skips

Oznaczenia

„.” test został zaliczony

„F” test nie został zaliczony

1 require ’test_helper ’23 class UsersControllerTest < ActionDispatch ::

IntegrationTest4 test ’akcja index przed i po dodaniu rekordu ’ do5 get users_url # akcja ’index ’6 assert response :success7 assert match ’Nowak’, @response.body8 assert no match ’Kowalski ’, @response.body9 ## #################

10 get new_user_url # akcja ’add ’11 assert response :found12 ## #################13 get users_url # akcja ’index ’14 assert response :success15 assert match ’Nowak’, @response.body16 assert match ’Kowalski ’, @response.body17 end18 #Powyższy fragment jest równoważny:19 # def test_akcja_index_przed_i_po_dodaniu_rekordu20 # ...21 # end22 end

test test/controllers/users controller test.rb

Dr inż. Stanisław Polak 162

Notatki

Notatki

Page 74: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Podstawy

Nadpisywanie konwencji nazewniczych

1 class User < ApplicationRecord2 self.table_name = "uzytkownik" #nazwa tabeli BD3 self.primary_key = "uzytkownik_id" #nazwa kolumny zawierającej klucz główny4 end

Dr inż. Stanisław Polak 163

Framework Ruby on Rails Model Podstawy

Wstawianie danych do BD

1 #Pierwszy sposób - w oparciu o hasz2 user = User.new(imię: "Jan", nazwisko: "Kowalski", pensja: 2000)3 user.save4 #lub5 user = User.create(imię: "Jan", nazwisko: "Kowalski", pensja: 2000)67 #Drugi sposób - w oparciu o blok8 user = User.create do |u|9 u.imię = "Jan"

10 u.nazwisko = "Kowalski"11 u.pensja = 200012 end13 #lub14 user = User.new do |u|15 u.imię = "Jan"16 u.nazwisko = "Kowalski"17 u.pensja = 200018 end19 user.save2021 #Trzeci sposób - poprzez "ręczne" ustawienie atrybutów22 user = User.new23 user.imię = "Jan"24 user.nazwisko = "Kowalski"25 user.pensja = 200026 user.save

Kontroler

Dr inż. Stanisław Polak 164

Notatki

Notatki

Page 75: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Podstawy

Pobieranie danych z BD

1 #Zwróć kolekcję ze wszystkimi uż ytkownikami (wszystkie rekordy)2 users = User.all34 #Zwróć pierwszego użytkownika (pierwszy rekord)5 user = User.first67 #Odszukaj pierwszego użytkownika o imieniu ’Jan ’ i zwróć go8 jan = User.find_by(imię: ’Jan’)9

10 #Odszukaj wszystkich Janów Kowalskich i posortuj wynik szukania w odwrotnej kolejności według datyutworzenia rekordu

11 users = User.where(imię: ’Jan’, nazwisko: ’Kowalski ’).order(’created_at DESC’)

Kontroler

Dr inż. Stanisław Polak 165

Framework Ruby on Rails Model Podstawy

Aktualizacja danych w BD

1 #Pierwszy sposób2 user = User.find_by(imię: ’Jan’)3 user.imię=’Jerzy’4 user.save56 #Drugi sposób7 user = User.find_by(imię: ’Jan’)8 user.update(imię: ’Jerzy’)

Kontroler

Dr inż. Stanisław Polak 166

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 76: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Podstawy

Usuwanie danych z BD

1 user = User.find_by(id:1)2 user.destroy

Kontroler

Dr inż. Stanisław Polak 167

Framework Ruby on Rails Model Podstawy

Silne parametry

1 class UserController < ApplicationController2 # http :// localhost :3000/ user/signup?user[name ]= ow3ned&user[

admin ]=13 def signup4 p params [:user] # {: name => "ow3ned" :admin => true}56 # Utworzenie nowego rekordu , który może być (później)

wstawiony do bazy danych7 @user = User.new(params [:user])8 #To spowoduje wygenerowanie wyjątku ActiveModel ::

ForbiddenAttributes9 #gdyż metoda używa ,,masowego przypisania ’’ (ang. ,,mass

assignment ’’),10 #bez bez wyraźnego kroku zezwolenia .1112 @user = User.new(user_params) #Tutaj wyjątku nie będzie13 end1415 def user_params16 params.require(:user).permit(:imię, :nazwisko , :pensja)17 end18 end

app/controllers/user controller.rb

1 $ rails console2 params = ActionController :: Parameters.new({3 user: {4 imię: ’Jan’,5 nazwisko: ’Kowalski ’,6 pensja: 2222,7 }8 })9 params

10 =>{"user"=>{"imię"=>"Jan", "nazwisko"=>"Kowalski", "pensja"= >2222}}

11 params [:user]12 => {"imię"=>"Jan", "nazwisko"=>"Kowalski", "pensja"= >2222}13 params.require(:user)14 => {"imię"=>"Jan", "nazwisko"=>"Kowalski", "pensja"= >2222}15 params.require(: nazwisko)16 ActionController :: ParameterMissing: param is missing or the

value is empty: nazwisko17 params [:user].permit(:imię)18 => {"imię"=>"Jan"}19 params [:user].permit(:imię,:nazwisko)20 => {"imię"=>"Jan", "nazwisko"=>"Kowalski"}21 params [:user].permit(: pesel)22 => {}

Dr inż. Stanisław Polak 168

Notatki

Notatki

Page 77: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Migracje

Anatomia migracji

1 class CreateUsers < ActiveRecord::Migration[5.1]2 # Wykonanie poniższej metody powoduje komenda: bin/rake db:migrate3 #Zadanie ’db:migrate ’ uruchamia również zadanie ’db:schema:dump ’4 def up5 create table :users do |t|6 #kolumna ’id’ zostanie utworzona automatycznie7 t.string :imię8 t.string :nazwisko9 t.decimal :pensja

10 t.timestamps # utworzenie kolumn: ’created_at ’, ’updated_at ’11 end12 end1314 # Wykonanie poniższej metody powoduje komenda: bin/rake db:rollback15 def down16 drop_table users17 end18 end

db/migrate/YYYYMMDDHHMMSS create users.rb

Dr inż. Stanisław Polak 170

Framework Ruby on Rails Model Migracje

Migracje odwracalne

1 class CreateUsers < ActiveRecord :: Migration [5.1]2 def change3 create_table :users do |t|4 t.string :imię5 t.string :nazwisko6 t.decimal :pensja7 t.timestamps8 end9 end

10 end

Dr inż. Stanisław Polak 171

Notatki

Notatki

Page 78: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Migracje

Tworzenie samodzielnej migracji

1 $ #bin/rails generate migration AddFieldsToUsers2 $ #bin/rails generate migration AddFieldsToUsers adres:string3 $ #bin/rails generate migration RemoveFieldsFromUsers pensja

1 class AddFieldsToUsers < ActiveRecord :: Migration [5.1]2 def change3 add column :users, :adres, :string4 end5 end

YYYYMMDDHHMMSS add fields to users.rb

1 class RemoveFieldsFromUsers < ActiveRecord :: Migration [5.1]2 def change3 remove_column :users , :pensja , :string4 end5 end

YYYYMMDDHHMMSS remove fields from users.rb

Dr inż. Stanisław Polak 172

Framework Ruby on Rails Model Migracje

Uruchamianie migracji

1 $ ls db/migrate/2 20140213155816 _create_users.rb3 20140214153539 _add_fields_to_users.rb4 20140214153735 _remove_fields_from_users.rb

1 $ bin/rake db:migrate VERSION=201402141535392 == CreateUsers: migrating ====================================================3 -- create_table (: users)4 -> 0.0044s5 == CreateUsers: migrated (0.0045s) ===========================================67 == AddFieldsToUsers: migrating ===============================================8 -- add_column (:users , :adres , :string)9 -> 0.0086s

10 == AddFieldsToUsers: migrated (0.0087s) ======================================11 $ bin/rake db:migrate VERSION=2014021315581612 == AddFieldsToUsers: reverting ===============================================13 -- remove_column (:users , :adres , :string)14 -> 0.0079s15 == AddFieldsToUsers: reverted (0.0194s) ======================================

Dr inż. Stanisław Polak 173

Notatki

Notatki

Page 79: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Asocjacje

Po co asocjacje?

Bez asocjacji

1 class Faculty < ApplicationRecord2 end34 class Student < ApplicationRecord5 end

Modele

1 @faculty = Faculty.create(name: "Informatyki")2 # Tworzenie nowego studenta wydziału Informatyki3 @student = Student.create(faculty_id: @faculty.id,firstName: "

Jan",lastName: "Kowalski")4 #Wyświetlenie , dla utworzonego studenta , nazwy wydziału5 puts Faculty.where(id: @student.faculty_id).first.name #Wyś

wietli: Informatyki6 #lub7 puts Faculty.find(@student.faculty_id).name #Wyświetli:

Informatyki8 #Usuwanie wydziału oraz studentów9 @students = Student.where(faculty_id: @faculty.id)

10 @students.each do |student|11 student.destroy12 end13 @faculty.destroy

Kontroler

Z asocjacjami

1 class Faculty < ApplicationRecord2 has_many :students , dependent: :destroy3 end45 class Student < ApplicationRecord6 belongs_to :faculty7 end

Modele

1 @faculty = Faculty.create(name: "Informatyki")2 #Tworzenie nowego studenta wydziału Informatyki3 @student = @faculty.students.create(firstName: "Jan",lastName:

"Kowalski")4 #Wyświetlenie , dla utworzonego studenta , nazwy wydziału5 puts @student.faculty.name #Wyświetli: Informatyki6 #Usuwanie wydziału oraz studentów7 @faculty.destroy

Kontroler

Dr inż. Stanisław Polak 174

Framework Ruby on Rails Model Asocjacje

Asocjacja „belongs to”

1 class Student < ApplicationRecord2 belongs_to :faculty3 end

Model

1 class CreateStudents < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.belongs_to :faculty5 t.string : firstName6 t.string : lastName7 end89 create_table :faculties do |t|

10 t.string :name11 end12 end13 end

Migracja

students

Model: Studentbelongs to: faculty

id: integer

faculty id: integer

firstName: string

lastName: string

faculties

Model: Faculty

id: integer

name: string

Dr inż. Stanisław Polak 176

Notatki

Notatki

Page 80: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Asocjacje

Asocjacja „has one”

1 class Student < ApplicationRecord2 has_one :locker3 end

Model

1 class CreateStudents < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string : firstName5 t.string : lastName6 end78 create_table :lockers do |t|9 t.belongs_to :student

10 t.integer :number11 end12 end13 end

Migracja

students

Model: Studenthas one: locker

id: integer

firstName: string

lastName: string

lockers

Model: Locker

id: integer

student id: integer

number: integer

Dr inż. Stanisław Polak 177

Framework Ruby on Rails Model Asocjacje

Asocjacja „has many”

1 class Faculty < ApplicationRecord2 has_many :students3 end

Model

1 class CreateFaculties < ActiveRecord :: Migration [5.1]2 def change3 create_table :faculties do |t|4 t.string :name5 end67 create_table :students do |t|8 t.belongs_to :faculty9 t.string :firstName

10 t.string :lastName11 end12 end13 end

Migracja

faculties

Model: Facultyhas many: students

id: integer

name: string

students

Model: Student

id: integer

faculty id: integer

firstName: string

lastName: string

Dr inż. Stanisław Polak 178

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 81: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Asocjacje

Asocjacja „has many :through”

1 class Student < ApplicationRecord2 has_many :classes3 has_many :teachers , through: classes4 end56 class Class < ApplicationRecord7 belongs_to :student8 belongs_to :teacher9 end

1011 class Teacher < ApplicationRecord12 has_many :classes13 has_many :students , through: classes14 end

Model

1 class CreateClasses < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :teachers do |t|9 t.string :name

10 end1112 create_table :classes do |t|13 t.belongs_to :student14 t.belongs_to :teacher15 t.datetime :term16 end17 end18 end

Migracja

students

Model: Studenthas many :classeshas many :teachers,:through=> :classes

id: integer

firstName: string

lastName: string

classes

Model: Classbelongs to :studentbelongs to :teacher

id: integer

student id: integer

teacher id: integer

term: datetime

teachers

Model: Teacherhas many :classeshas many :students,:through=> :classes

id: integer

name: string

Dr inż. Stanisław Polak 179

Framework Ruby on Rails Model Asocjacje

Asocjacja „has one :through”

1 class Student < ApplicationRecord2 has_one :account3 has_one :account_history , through: :account4 end56 class Account < ApplicationRecord7 belongs_to :student8 has_one :account_history9 end

1011 class AccountHistory < ApplicationRecord12 belongs_to :account13 end

Model

1 class CreateAccountHistories < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :accounts do |t|9 t.belongs_to :student

10 t.string :account_number11 end1213 create_table :account_histories do |t|14 t.belongs_to :account15 t.integer :return_book_punctuality_rating16 end17 end18 end

Migracja

students

Model: Studenthas one :accounthas one :account history, :through=> :account

id: integer

firstName: string

lastName: string

accounts

Model: Accountbelongs to :studenthas one :account history

id: integer

student id: integer

account number: string

account histories

Model: AccountHistorybelongs to :account

id: integer

account id: integer

return book punctuality rating: integer

Dr inż. Stanisław Polak 180

Notatki

Notatki

Page 82: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Asocjacje

Asocjacja „has and belongs to many”

1 class Student < ApplicationRecord2 has_and_belongs_to_many :teachers3 end45 class Teacher < ApplicationRecord6 has_and_belongs_to_many :students7 end

Model

1 class CreateStudentsAndTeachers < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :teachers do |t|9 t.string :name

10 end1112 create_table :students_teachers , id: false do |t| #id:

false - tabela nie będzie zawierała klucza głównego13 t.belongs_to :student14 t.belongs_to :teacher15 end16 end17 end

Migracja

students

Model: Studenthas and belongs to many :teachers

id: integer

firstName: string

lastName: string

students teachers

student id: integer

teacher id: integer

teachers

Model: Teacherhas and belongs to many :students

id: integer

name: string

Dr inż. Stanisław Polak 181

Framework Ruby on Rails Model Asocjacje

Asocjacja polimorficzna

1 class Picture < ApplicationRecord2 belongs_to :imageable , polymorphic: true3 end45 class Student < ApplicationRecord6 has_many :pictures , as: :imageable7 end89 class Teacher < ApplicationRecord

10 has_many :pictures , as: :imageable11 end

Model

1 class CreatePictures < ActiveRecord :: Migration [5.1]2 def change3 create_table :pictures do |t|4 t.string :name5 t.references :imageable , polymorphic: true6 end7 end8 end

Migracja

students

Model: Studenthas many :pictures, :as => :imageable

id: integer

firstName: string

lastName: string

pictures

Model: Picturebelongs to :imageable,polymorphic: true

id: integer

name: string

imageable id: integer

imageable type: string

teachers

Model: Teacherhas many :pictures, :as => :imageable

id: integer

name: string

Dr inż. Stanisław Polak 182

Notatki

Notatki

Page 83: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Czynności wstępne

1 $ rails new library --skip -action -cable --skip -active -storage --skip -action -mailer2 $ cd library3 $ vi config/routes.rb4 $ bin/rake routes5 Prefix Verb URI Pattern Controller#Action6 books GET /books (.: format) books#index7 POST /books (.: format) books#create8 new_book GET /books/new(.: format) books#new9 edit_book GET /books /:id/edit (.: format) books#edit

10 book GET /books/:id(.: format) books#show11 PATCH /books /:id(.: format) books#update12 PUT /books/:id(.: format) books#update13 DELETE /books/:id(.: format) books#destroy14 subjects GET /subjects (.: format) subjects#index15 POST /subjects (.: format) subjects#create16 new_subject GET /subjects/new (.: format) subjects#new17 edit_subject GET /subjects /:id/edit (.: format) subjects#edit18 subject GET /subjects /:id(.: format) subjects#show19 PATCH /subjects /:id(.: format) subjects#update20 PUT /subjects /:id(.: format) subjects#update21 DELETE /subjects /:id(.: format) subjects#destroy

1 Rails.application.routes.draw do2 # maps HTTP verbs to controller actions automatically3 resources :books4 resources :subjects5 end

config/routes.rb

Dr inż. Stanisław Polak 184

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Konfigurowanie bazy danych

1 $ vi library/config/database.yml

1 # SQLite version 3.x2 # gem install sqlite33 #4 # Ensure the SQLite 3 gem is defined in your Gemfile5 # gem ’sqlite3 ’6 #7 default: &default8 adapter: sqlite39 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

10 timeout: 50001112 development:13 <<: *default14 database: db/development.sqlite31516 # Warning: The database defined as "test" will be erased and17 # re - generated from your development database when you run "rake ".18 # Do not set this db to the same as development or production .19 test:20 <<: *default21 database: db/test.sqlite32223 production:24 <<: *default25 database: db/production.sqlite3

config/database.yml

Dr inż. Stanisław Polak 185

Notatki

Notatki

Page 84: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Pliki modelu

1 $ bin/rails generate model book2 invoke active_record3 create db/migrate /20140203134304 _create_books.rb4 create app/models/book.rb5 invoke test_unit6 create test/models/book_test.rb7 create test/fixtures/books.yml8 $ bin/rails generate model subject9 invoke active_record

10 create db/migrate /20140203134316 _create_subjects.rb11 create app/models/subject.rb12 invoke test_unit13 create test/models/subject_test.rb14 create test/fixtures/subjects.yml15 $ bin/rake db:create

1 class Book < ApplicationRecord2 belongs to :subject3 end

app/models/book.rb

1 class Subject < ApplicationRecord2 has many :books3 end

app/models/subject.rb

Dr inż. Stanisław Polak 186

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Pliki migracji

1 class CreateBooks < ActiveRecord :: Migration [5.1]2 def change3 create_table :books do |t|4 t.belongs_to :subject #Utwórz klucz obcy5 t.string :title , :limit => 326 t.float :price7 t.text :description8 t.timestamp :created_at9 end

10 end11 end

db/migrate/* create books.rb

1 class CreateSubjects < ActiveRecord :: Migration [5.1]2 def change3 create_table :subjects do |t|4 t.string :name5 end6 end7 end

db/migrate/* create subjects.rb

1 CREATE TABLE "books" (2 "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,3 "subject_id" integer ,4 "title" varchar (32),5 "price" float ,6 "description" text ,7 "created_at" datetime8 );

1 CREATE TABLE "subjects" (2 "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,3 "name" varchar (255)4 );

1 Subject.create :name => "Physics"2 Subject.create :name => "Mathematics"3 Subject.create :name => "Chemistry"4 Subject.create :name => "Psychology"5 Subject.create :name => "Geography"

db/seeds.rb

1 $ bin/rake db:migrate2 $ bin/rake db:seed

Dr inż. Stanisław Polak 187

Notatki

Notatki

Page 85: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Kontroler dla książek

1 $ bin/rails generate controller books2 create app/controllers/books_controller.rb3 ...

1 class BooksController < ApplicationController2 def index3 end45 def show6 end78 def create9 end

1011 def new12 end1314 def edit15 end1617 def update18 end1920 def destroy21 end22 end

app/controllers/books controller.rb

Dr inż. Stanisław Polak 188

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Wyświetlanie listy książek

1 class BooksController < ApplicationController2 def index3 @books = Book.all4 @subjects = Subject.all5 end6 ...7 end

app/controllers/books controller.rb

1 <% if @books.blank? %>2 <p>There are not any books currently in the system.</p>3 <% else %>4 <ul id="subjects">5 <% @subjects.each do |subject| %>6 <li><%= link_to subject.name , subject_path(subject) %></li>7 <% end %>8 </ul>9 <p>These are the current books in our system </p>

10 <ul id="books">11 <% @books.each do |book| %>12 <li>13 <%= link_to book.title , book_path(book) %> <!-- np. /books /3 -->14 <%= link_to ’Edit ’, edit_book_path(book) %> <!-- np. /books /3/ edit -->15 <%= link_to ’Destroy ’, book_path(book), method: :delete , data: { confirm: ’Are you sure?’ } %>16 <% end %>17 </ul>18 <% end %>19 <p><%= link_to "Add new Book", new_book_path %></p> <!-- /books/new -->

app/views/books/index.html.erb

Dr inż. Stanisław Polak 189

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 86: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Dodawanie nowej książki

1 class BooksController < ApplicationController2 ...3 def new4 end56 def create7 params.permit! #Wymagane w RoR 4.08 @book = Book.new(params [:book])9 if @book.save

10 redirect_to books_path # przekierowanie do akcji books#index

11 else12 render ’new’13 end14 end15 ...16 end

app/controllers/books controller.rb

1 <h1>Add new book</h1>2 <%= form_with model: Book.new , local: true do |f| %>3 <p>4 <%= f.label :title %><br>5 <%= f.text_field :title %>6 </p>7 <p>8 <%= f.label :price %><br>9 <%= f.text_field :price %>

10 </p>11 <p>12 <%= f.label :subject %><br>13 <%= collection_select (:book ,:subject_id ,Subject.all ,:id ,:

name) %>14 </p>15 <p>16 <%= f.label :description %><br>17 <%= f.text_area :description %>18 </p>19 <p>20 <%= f.submit %>21 </p>22 <% end %>23 <%= link_to ’Back ’, books_path %>

app/views/books/new.html.erb

Dr inż. Stanisław Polak 190

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Wyświetlanie książki

1 class BooksController < ApplicationController2 ...3 def show4 @book = Book.find(params [:id])5 end6 ...7 end

app/controllers/books controller.rb

1 <h1><%= @book.title %></h1>2 <p><strong >Price: </strong > $<%= @book.price %><br />3 <strong >Subject: </strong > <%= link_to @book.subject.name ,

subject_path(@book.subject.id) %><br />4 <strong >Created Date:</strong > <%= @book.created_at %><br />5 </p>6 <p><%= @book.description %></p>7 <hr />8 <%= link_to ’Back ’, books_path %>

app/views/books/show.html.erb

Dr inż. Stanisław Polak 191

Notatki

Notatki

Page 87: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Edycja książki

1 class BooksController < ApplicationController2 ...3 def edit4 @book = Book.find(params [:id])5 @subjects = Subject.all6 end78 def update9 @book = Book.find(params [:id])

10 if @book.update(params [:book]. permit (:title , :price , :description))11 redirect_to @book12 else13 render ’edit’14 end15 end16 ...17 end

app/controllers/books controller.rb

1 <h1>Edit Book Detail </h1>2 <%= form_with model: @book , local: true do |f| %>3 <%# można i tak:4 form_with scope: :book , url: book_path(@book), local: true , method: :

patch do |f|5 local: true - nie używaj AJAX -a do wysyłania zawartości formularza6 %>78 <p>9 <%= f.label :title %><br>

10 <%= f.text_field :title %>11 </p>12 <p>13 <%= f.label :price %><br>14 <%= f.text_field :price %>15 </p>16 <p>17 <%= f.label :subject %><br>18 <%= collection_select (:book ,:subject_id ,@subjects ,:id ,:name) %>19 </p>20 <p>21 <%= f.label :description %><br>22 <%= f.text_area :description %>23 </p>24 <p>25 <%= f.submit %>26 </p>27 <% end %>28 <%= link_to ’Back ’, books_path %>

app/views/books/edit.html.erb

Dr inż. Stanisław Polak 192

Framework Ruby on Rails Model Przykład tworzenia aplikacji

Kasowanie książki

1 class BooksController < ApplicationController2 ...3 def destroy4 book = Book.find(params [:id])5 book.destroy6 redirect_to books_path7 end8 ...

app/controllers/books controller.rb

Dr inż. Stanisław Polak 193

Notatki

Notatki

Page 88: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Walidacja

Wyświetlanie błędów walidacji w widoku

1 <%= form_with scope: :book , url: books_path do |f| %>2 <% if @book.errors.any? %>3 <div id="error_explanation">4 <h2 ><%= pluralize(@book.errors.count , "error") %> prohibited this book from being saved:</h2 >5 <ul>6 <% @book.errors.full_messages.each do |msg| %>7 <li ><%= msg %></li >8 <% end %>9 </ul >

10 </div >11 <% end %>12 ...13 <!-- Pola formularza -->14 <% end %>

app/views/users/new.html.erb

Dr inż. Stanisław Polak 196

Framework Ruby on Rails Model Walidacja

Pomocnicy walidacji

1 class Book < ApplicationRecord2 belongs_to :subject3 validates :title , presence:true4 validates :price , numericality: true5 end

Dr inż. Stanisław Polak 197

Notatki

Notatki

Page 89: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Testy jednostkowe

Osprzęt (ang. Fixture)

I Sposób organizowania danych testowychI Podstawowe dane, którymi zapełniana jest baza danychI Jest niezależny od silnika bazy danychI Zapisujemy w formacie YAMLI Jeden model — jeden plik z osprzętem

1 #komentarz2 one:3 title: O obrocie sfer niebieskich4 description: Biały kruk5 subject: physics6 two:7 title: Lenin , działa wybrane8 price: 109 subject: physics

test/fixtures/books.yml

1 physics:2 name: Physics

test/fixtures/subjects.yml

Dr inż. Stanisław Polak 198

Framework Ruby on Rails Model Testy jednostkowe

Testy jednostkowe modeli

1 require ’test_helper ’23 class BookTest < ActiveSupport :: TestCase4 test "not_valid" do5 book = books(:one)6 assert book.valid?, "Błąd walidacji"?7 end8 #Powyższy fragment jest równoważny:9 # def test_not_valid

10 # ...11 # end1213 test "valid" do14 book = books(:two)15 assert book.valid?, "Błąd walidacji"?16 end17 end

test/models/book test.rb”

Dr inż. Stanisław Polak 199

Notatki

Notatki

Page 90: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Model Testy jednostkowe

Przygotowywanie aplikacji do testowania i uruchamianie testów

1 $ bin/rake db:migrate2 $ bin/rake test3 Run options: --seed 1042345 # Running tests:67 F.89 Finished tests in 0.118807s, 16.8340 tests/s, 16.8340 assertions/s.

1011 1) Failure:12 BookTest# test_not_valid [/ home/polak/library/test/models/book_test .rb :7]:13 Błąd walidacji1415 2 tests , 2 assertions , 1 failures , 0 errors , 0 skips

Oznaczenia

„F” test nie został zaliczony

„.” test został zaliczony

Dr inż. Stanisław Polak 200

Framework Ruby on Rails Widok

Składniki warstwy widoku

I SzablonyI Szablony częścioweI Układy

1 <table >2 <% @books.each do |book| %>3 <tr>4 <td ><%= book.title %></td>5 <td ><%= book.price %></td>6 <td ><%= book.description %></td>7 </tr >8 <% end %>9 </table >

index.html.erb

1 json.array!( @books) do |book|2 json.extract! book , :id , :title , :price , :description3 end

index.json.jbuilder

Dr inż. Stanisław Polak 201

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 91: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Widok

Tworzenie układu1 <!DOCTYPE html >2 <html >3 <head >4 <title >Library Info System | <%= yield(:title) %></title >5 <%= stylesheet_link_tag "application", media: "all", "data -turbolinks -track" => true %>6 <%= javascript_include_tag "application", "data -turbolinks -track" => true %>7 <%= csrf_meta_tags %>8 </head >9 <body id="library">

10 <header >11 <h1>Library Info System </h1>12 <h3>Library powered by Ruby on Rails </h3 >13 </header >14 <main >15 <%= yield %>16 </main >17 </body >18 </html >

app/views/layouts/standard.html.erb

1 <% content for(:title , ’Home’) %>2 ...

app/views/books/index.html.erb

1 class ApplicationController < ApplicationController2 layout ’standard’3 ...

app/controllers/application controller.rb

Dr inż. Stanisław Polak 202

Framework Ruby on Rails Widok

Tworzenie pomocnika

Library Info System |

1 module ApplicationHelper23 def full_title(page_title)4 base_title = "Library Info System"5 if page_title.empty?6 base_title7 else8 "#{ base_title} | #{ page_title}"9 end

10 end11 end

app/helpers/application helper.rb

1 ...2 <title ><%= full_title(yield(:title)) %></title >3 ...

app/views/layouts/standard.html.erb

Dr inż. Stanisław Polak 203

Notatki

Notatki

Page 92: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Widok

Przesyłanie strumieniowe szablonów

1 render stream: true

Kontroler

1 <html >2 <head ><title ><%= yield :title %></title ></head >3 <body ><%= yield %></body >4 </html >

Układ

1 <% content for :title , "Main" %>2 Hello3 <% content for :title , " page" %>

Szablon

1 <html >2 <head ><title >Main page </title ></head >3 <body >Hello </body >4 </html >

Wynikowy dokument

1 <% provide :title , "Main" %>2 Hello3 <% content_for :title , " page" %>

Szablon

1 <html >2 <head ><title >Main </title ></head >3 <body >Hello </body >4 </html >

Wynikowy dokument

Dr inż. Stanisław Polak 204

Framework Ruby on Rails Widok

Plik ze stylami CSS

1 body {font -family: Helvetica , Geneva , Arial , sans -serif; font -size: small; font -color: #000; background -color: #fff; width: 760px;margin: 0 auto;}

23 a:link , a:active , a:visited {color: #CD0000; }45 input {margin -bottom: 5px; }67 p {line -height: 150%; }89 header {text -align: center;padding -bottom: 15px; }

1011 main {float: left; width: 450px; padding: 10px; }1213 main h3 {margin -top: 15px; }1415 ul#books {list -style -type: none; }1617 ul#books li {line -height: 140%; }1819 ul#subjects {width: 700px; text -align: center; padding: 5px; background -color: #ececec; border: 1px

solid #ccc; margin -bottom: 20px; }2021 ul#subjects li {display: inline; padding -left: 5px; }

app/assets/stylesheets/library.css

Dr inż. Stanisław Polak 205

Notatki

Notatki

Page 93: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Widok

Kontroler dla przedmiotów

1 $ bin/rails generate controller subjects2 create app/controllers/subjects_controller.rb3 ...

1 class SubjectsController < ApplicationController2 def index3 end45 def show6 end78 def create9 end

10 end

app/controllers/subjects controller.rb

Dr inż. Stanisław Polak 206

Framework Ruby on Rails Widok

Wyświetlanie listy przedmiotów

1 class SubjectsController < ApplicationController2 def index3 @subjects = Subject.all4 end5 ...6 end

app/controllers/subjects controller.rb

1 <h1>Listing Subjects </h1>2 <ul id="subject_list">3 <% @subjects.each do |subject| %>4 <li><%= link_to subject.name , subject_path(subject) %> <%= "(#{ subject.books.count})" -%></li>5 <% end %>6 </ul>

app/views/subjects/index.html.erb

Dr inż. Stanisław Polak 207

Notatki

Notatki

Page 94: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Widok

Wyświetlanie przedmiotu

1 class SubjectsController < ApplicationController2 ...3 def show4 @subject = Subject.find(params [:id])5 end6 ...7 end

app/controllers/subjects controller.rb

1 <h1><%= @subject.name -%></h1>2 <ul>3 <% @subject.books.each do |book| %>4 <li><%= link_to book.title , book_path(book) -%>5 <% end %>6 </ul>7 <%= link_to ’Back ’, subjects_path %>

app/views/subjects/show.html.erb

Dr inż. Stanisław Polak 208

Framework Ruby on Rails Widok

Dodawanie nowego przedmiotu przy użyciu AJAX-a

1 class SubjectsController < ApplicationController2 ...3 def create4 params.permit!5 @subject = Subject.new(name: params[’name’])6 if @subject.save7 render partial: ’subject ’, object: @subject8 end9 end

10 ...11 end

app/controllers/subjects controller.rb

1 <h1>Listing Subjects </h1>2 <ul id="subject_list">3 ...4 </ul>5 <%# ------------------------ %>6 <p id="add_link">7 <a href="#" data-remote="true" onclick="8 var element = document.querySelector (’#add_link ’);9 element.parentNode.removeChild(element);

10 document.querySelector (’#add_subject ’).style.display = ’block ’;

11 ">Add a Subject </a></p>12 <div id="add subject" style="display:none;">13 <%= form with model: @subject do |f| %>14 <%= f.label :name %><br>15 <%= f.text_field :name %>16 <%= submit_tag ’Add ’ %>17 <% end %>18 </div>

app/views/subjects/index.html.erb

1 <li id="subject_ <%= subject.id %>">2 <%= link_to subject.name , subject_path(subject) %>3 <%= "(#{ subject.books.count})" -%>4 </li>

app/views/subjects/ subject.html.erb

1 document.addEventListener "turbolinks:load", ->2 document.querySelectorAll("form").forEach ->3 document.body.addEventListener ’ajax:success ’, (event) ->4 element = document.createRange ().

createContextualFragment(event.detail [2]. response);

5 document.querySelector("#subject_list").appendChild(element);

6 document.body.addEventListener ’ajax:error ’, ->7 element = document.createRange ().

createContextualFragment("<p>ERROR </p>");8 document.querySelector("#subject_list").appendChild(

element);

app/assets/javascripts/subjects.coffee

Dr inż. Stanisław Polak 209

Notatki

Notatki

Page 95: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Widok

Testy integracyjne aplikacji

1 bin/rails generate integration_test books_flows2 vim test/integration/books_flows_test.rb

1 require ’test_helper ’23 class BooksFlowsTest < ActionDispatch::IntegrationTest4 test "browse site" do5 get "/books"6 assert_response :success # Czy status odpowiedzi to 20078 get "/books/new"9 assert_response :success

1011 post "/books", params: { # Żądanie zasobu HTML12 # post "/ books.json", params: { # Żądanie zasobu JSON13 book: {14 title: "Matematyka",15 price: 116 }17 }18 # Przykładowa asercja dla JSON -a19 # json_response = JSON.parse(response.body)20 # assert_equal ’Matematyka ’,json_response [" title "]2122 assert_response :redirect23 follow redirect!24 assert_response :success2526 books = Book.all27 assert_equal 3, books.size28 book = books[books.size -1]29 assert_equal "Matematyka", book.title30 assert_equal 1, book.price31 end32 end

test/integration/books flows test.rb

Dr inż. Stanisław Polak 210

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Umiędzynarodowienie i lokalizacja

Umiędzynarodowienie polega na dodaniu do aplikacji możliwości wpisywania, przetwarzania iwyświetlania (generowania) tekstu w różnych językach.

Lokalizacja jest procesem polegającym na dostosowaniu aplikacji do określonych ustawieńregionalnych (przetłumaczenie tekstów na odpowiedni język, dostosowanie formatuwaluty, formatu liczb, formatu dat, itp.).

Dr inż. Stanisław Polak 211

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 96: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Gem I18n

Co oferujeI Wsparcie dla języka angielskiego i języków do niego podobnychI Ułatwienie dostosowania i rozbudowywania aplikacji dla innych języków

Ogólna struktura gem-aI Publiczne API frameworku I18n — moduł Ruby z publicznymi metodami i definicjami,

określającymi sposób działania bibliotekiI Domyślny back-end (celowo nazywany prostym back-endem) , implementujący powyższe metody

Dr inż. Stanisław Polak 212

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Konfiguracja modułu I18n

1 en:2 title: "Library Info System"3 info: "Library powered by Ruby on Rails %{ version

}"

config/locales/en.yml

1 pl:2 title: "Biblioteczny System Informacyjny"3 info: "Biblioteka w oparciu o Ruby on Rails %{

version}"

config/locales/pl.yml

1 ...2 # The default locale is :en and all translations from config/locales /*.rb ,yml are auto loaded.3 # config.i18n.load_path += Dir[Rails.root.join(’my ’, ’locales ’, ’*.{rb ,yml}’).to_s]4 # config.i18n. default_locale = :de5 ...

config/application.rb

1 $ vi Gemfile2 $ bundle install

Instalowanie gem-a ’rails-18n’

1 ...2 gem ’rails -i18n’

Gemfile

Dr inż. Stanisław Polak 213

Notatki

Notatki

Page 97: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Wyświetlanie tekstu wielojęzycznego

1 ...2 <header >3 <h1 ><%= t(’title’) %></h1>4 <h3 ><%= t(’info’,version: Rails.version) %></h3>5 <p><%= l Time.now %></p>6 </header >7 ...

app/views/layouts/standard.html.erb

1 <% if @books.blank? %>2 <p>Obecnie w systemie nie ma żadnych książek </p>3 <% else %>4 <ul id="subjects">5 <% @subjects.each do |subject| %>6 <li ><%= link_to subject.name , subject_path(subject) %></li>7 <% end %>8 </ul >9 <p>Oto książki znajdujące się w naszym systemie </p>

10 <ul id="books">11 <% @books.each do |book| %>12 <li>13 <%= link_to book.title , book_path(book) %>14 <%= link_to ’Edytuj ’, edit_book_path(book) %>15 <%= link_to ’Usuń’, book_path(book), method: :delete , data: { confirm: ’Jesteś pewien?’ } %>16 <% end %>17 </ul >18 <% end %>19 <p><%= link_to "Dodaj nową książkę", new_book_path -%></p>

app/views/books/index.pl.html.erb

Dr inż. Stanisław Polak 214

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

„Leniwe” wyszukiwanie

1 pl:2 layouts:3 standard:4 title: "Biblioteczny System Informacyjny"5 info: "Biblioteka w oparciu o Ruby on Rails %{ version}"

config/locales/pl.yml

1 ...2 <header >3 <h1 ><%= t(’.title’) %></h1>4 <h3 ><%= t(’.info’,version: Rails.version) %></h3>5 </header >6 ...

app/views/layouts/standard.html.erb

Dr inż. Stanisław Polak 215

Notatki

Notatki

Page 98: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Określanie języka ustawień regionalnych

I Na podstawie parametrów URLI Na podstawie nazwy domenyI Na podstawie informacji

dostarczonych przez klientaI Nagłówek „Accept-Language”I Baza GeoIP lub podobneI Profil użytkownika

1 #Przykładowy URL: http :// localhost :3000/ books?locale=pl2 class ApplicationController < ActionController ::Base3 before_action :set_locale45 def set_locale6 I18n.locale = params [: locale] || I18n.default_locale7 end8 end

app/controllers/application controller.rb

Dr inż. Stanisław Polak 216

Framework Ruby on Rails Lokalizacja i umiędzynarodowienie

Tłumaczenie rekordów bazy danych

1 $vi Gemfile2 $ bundle install3 $ vi app/models/book.rb4 $ bin/rails generate migration AddTranslationToBooks5 $ vi db/migrate /* _add_translation_to_books.rb6 $ bin/rake db:migrate7 $ vi app/controllers/books_controller.rb

1 source ’https :// rubygems.org’2 gem ’globalize ’

Gemfile

Dr inż. Stanisław Polak 217

Notatki

Notatki

Page 99: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Gem „Devise”Ogólna charakterystyka

I Oparty na Rack-uI Kompletne rozwiązanie MVC oparte na silnikach RailsI Jest oparty na koncepcji modułowej: „Używasz tylko tego, czego naprawdę potrzebujesz”

Moduły

1. Database Authenticatable

2. Omniauthable

3. Confirmable

4. Recoverable

5. Registerable

6. Rememberable

7. Trackable

8. Timeoutable

9. Validatable

10. Lockable

Dr inż. Stanisław Polak 218

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Instalowanie gema

1 $ vi Gemfile2 $ bundle install

1 ...2 gem ’devise ’3 gem ’devise -i18n’

Gemfile

Dr inż. Stanisław Polak 219

Notatki

Notatki

Page 100: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Inicjalizacja

1 $ bin/rails generate devise:install2 create config/initializers/devise.rb3 create config/locales/devise.en.yml4 =========================================56 Some setup you must do manually if you haven ’t yet:7 ...89 $ vi config/initializers/devise.rb

1 # Use this hook to configure devise mailer , warden hooks andso forth.

2 # Many of these configuration options can be set straight inyour model.

3 Devise.setup do |config|4 # The secret key used by Devise. Devise uses this key to

generate5 # random tokens. Changing this key will render invalid all

existing6 # confirmation , reset password and unlock tokens in the

database.7 config.secret_key = ’6

b255d21928f0ba7669192e8d286c139cc4b2dea ’89 # ==> Mailer Configuration

10 # Configure the e-mail address which will be shown in Devise:: Mailer ,

11 # note that it will be overwritten if you use your ownmailer class

12 # with default "from" parameter.13 config.mailer_sender = ’please -change -me -at-config -

initializers [email protected]’1415 # Configure the class responsible to send e-mails.16 # config.mailer = ’Devise :: Mailer ’17 ...

config/initializers/devise.rb

Dr inż. Stanisław Polak 220

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Konfigurowanie

1 config.action_mailer.default_url_options = { :host => ’localhost :3000’ }

config/environments/development.rb

1 <main >2 <p class="notice" ><%= notice %></p>3 <p class="alert" ><%= alert %></p>4 <%= yield %>5 </main >

app/views/layouts/standard.html.erb

1 ...2 root :to => "books#index"

config/routes.rb”

Dr inż. Stanisław Polak 221

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 101: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Dodawanie „Devise” do modelu

1 $ bin/rails generate devise user2 invoke active_record3 create db/migrate /20140219113545 _devise_create_users.rb4 create app/models/user.rb5 invoke test_unit6 create test/models/user_test.rb7 create test/fixtures/users.yml8 insert app/models/user.rb9 route devise_for :users

1011 $ bin/rake db:migrate12 == DeviseCreateUsers: migrating ==============================================13 -- create_table (:users)14 -> 0.0404s15 -- add_index (:users , :email , {: unique=>true})16 -> 0.0014s17 -- add_index (:users , :reset_password_token , {: unique=>true})18 -> 0.0013s19 == DeviseCreateUsers: migrated (0.0439s) =====================================

Dr inż. Stanisław Polak 222

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Dodawanie atrybutu „admin”

1 $ bin/rails generate migration AddAdminToUsersadmin:boolean

2 invoke active_record3 create db/migrate /20140221085221

_add_admin_to_users.rb45 $ vi db/migrate /* _add_admin_to_users.rb67 $ bin/rake db:migrate8 == AddAdminToUsers: migrating ==9 -- add_column (:users , :admin , :boolean , {: default=>

false})10 -> 0.0213s11 == AddAdminToUsers: migrated (0.0215s) ==

1 class AddAdminToUsers < ActiveRecord :: Migration2 def change3 add_column :users , :admin , :boolean , default:

false4 end5 end

db/migrate/* add admin to users.rb

Dr inż. Stanisław Polak 223

Notatki

Notatki

Page 102: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Wymuszanie uwierzytelniania

1 class ApplicationController < ActionController ::Base2 protect_from_forgery with: :exception3 before_action :set_locale ,:authenticate user! #Tekst występujący po znaku ’_’ jest nazwą modelu4 ...5 end

app/controllers/application controller.rb

Dr inż. Stanisław Polak 224

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Wyświetlanie informacji o zalogowanym użytkowniku

1 ...2 <aside >3 <% if user_signed_in? %>4 <%=t(’.logged_html ’,email: current_user.email) %>5 <br>6 <%= link_to t(’.edit_profile ’), edit_user_registration_path %> |7 <%= link_to t(’.logout ’), destroy_user_session_path , method: :delete %>8 <% else %>9 <%= link_to t(’.sign_up ’), new_user_registration_path %> |

10 <%= link_to t(’.login ’), new_user_session_path %>11 <% end %>12 </aside >13 </body >14 </html >

app/views/layouts/standard.html.erb

1 en:2 layouts:3 standard:4 ...5 logged_html: "Logged in as <strong >%{ email}</strong >"6 edit_profile: "Edit profile"7 logout: "Logout"8 sign_up: "Sign up"9 login: "Login"

config/locales/en.yml

1 en:2 layouts:3 standard:4 ...5 logged_html: "Zalogowany jako <strong >%{ email}</strong >"6 edit_profile: "Edytuj profil"7 logout: "Wyloguj"8 sign_up: "Zarejestruj się"9 login: "Zaloguj"

config/locales/pl.yml

Dr inż. Stanisław Polak 225

Notatki

Notatki

Page 103: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”

Rejestracja i logowanie

Dr inż. Stanisław Polak 226

Framework Ruby on Rails Gem „Pundit”

Gem „Pundit”Ogólna charakterystyka

I Umożliwia stworzenie prostego, solidnego i skalowalnego systemu autoryzacjiI Autoryzacja w oparciu o klasy politykI Pozwala określić zakres widoczności rekordów BD dla użytkownikówI Wspomaga obsługę „silnych” parametrów

Dr inż. Stanisław Polak 227

Notatki

Notatki

Page 104: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Gem „Pundit”

Instalowanie gema

1 $ vi Gemfile2 $ bundle install

1 ...2 gem ’pundit ’

Gemfile

Dr inż. Stanisław Polak 228

Framework Ruby on Rails Gem „Pundit”

Dodawanie „Pundit” do kontrolera

1 class ApplicationController < ActionController ::Base2 include Pundit3 ...4 end

app/controllers/application controller.rb

Dr inż. Stanisław Polak 229

Notatki

Notatki

Page 105: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Gem „Pundit”

Przykładowa polityka dostępu

Zwykły użytkownikI Może wyświetlać listę książekI Może wyświetlać informacje o pojedynczej

książceI Może usuwać książki z Chemii

AdministratorI Może wyświetlać listę książekI Może wyświetlać informacje o pojedynczej

książceI Może dodawać nowe książkiI Może usuwać książkiI Może edytować książki

Dr inż. Stanisław Polak 230

Framework Ruby on Rails Gem „Pundit”

Tworzenie pliku z polityką dostępu

1 $ bin/rails generate pundit:install2 create app/policies/application_policy.rb3 $ cat app/policies/application_policy.rb4 $ vi app/policies/book_policy.rb

1 class BookPolicy < ApplicationPolicy2 def create?3 user.admin?4 end56 def update?7 user.admin?8 end9

10 def destroy?11 user.admin? or record.subject.name == "Chemistry"12 end13 end

app/policies/book policy.rb

Dr inż. Stanisław Polak 231

Mat

eriał

ydla

studen

tów

Infor

mat

yki wyd

ziału

IET

AGHw

Krako

wieNotatki

Notatki

Page 106: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Gem „Pundit”

Sprawdzanie uprawnień w obrębie widoku

1 ...2 <ul id="books">3 <% @books.each do |book| %>4 <li>5 <%= link_to book.title , book_path(book) %>6 <% if policy(book).edit? %>7 <%= link_to ’Edytuj ’, edit_book_path(book) %>8 <% end %>9 <% if policy(book).destroy? %>

10 <%= link_to ’Usuń’, book_path(book), method: :delete , data: { confirm: ’Jesteś pewien?’ } %>11 <% end %>12 <% end %>13 </ul >14 ...15 <p>16 <% if policy(Book.new).create? %>17 <%= link_to "Dodaj nową książkę", new_book_path -%>18 <% end %>19 </p>

app/views/books/index.pl.html.erb

Dr inż. Stanisław Polak 232

Framework Ruby on Rails Gem „Pundit”

Użycie autoryzacji w kontrolerze

1 class BooksController < ApplicationController2 after_action :verify authorized, :except => :index3 ...4 #http :// localhost :3000/ books/new5 def new6 @book = Book.new7 #Przerwij proces wykonywania akcji , jeżeli użytkownik nie ma stosownych uprawnień8 authorize @book #raise "not authorized " unless BookPolicy .new(current_user , @book).new?9 end

10 ...11 end

app/controllers/books controller.rb

Dr inż. Stanisław Polak 233

Notatki

Notatki

Page 107: Programowanie w jezyku Rubypolak/wyklady/jezyki/ruby.pdf · 2020-04-17 · 4 dane2=readlines() 5 puts’#####’ 6 puts"Wprowadzone dane:" 7 putsdane1 8 putsdane2 9 puts’-----’

Framework Ruby on Rails Źródła

Źródła I

I Jamis Buck. Method visibility in Ruby. url:http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby.

I Radosław Bułat. Blog. url: http://radarek.jogger.pl/.

I RoR community. Ruby on Rails guides. url: http://guides.rubyonrails.org/.

I Michael Hartl. Ruby on Rails Tutorial. url: https://www.railstutorial.org/book.

I Blake Mizerany. Sinatra - documentation. url:http://www.sinatrarb.com/documentation.html.

I Michael Morin. Using Rack. url: http://ruby.about.com/od/rack/a/Using-Rack.htm.

I Aleksander Pohl. Ruby intro. url: http://www.apohllo.pl/dydaktyka/ruby/intro/.

I Arnau Sanches. Functional Programming with Ruby. url:http://www.slideshare.net/tokland/functional-programming-with-ruby-9975242.

I Sergio Tapia. How to use Rails 4.1 ActionPack Variants. url:http://tech.pro/tutorial/2049/how-to-use-rails-41-actionpack-variants.

I Techotopia.com. Ruby Essentials. url:http://www.techotopia.com/index.php/Ruby_Essentials.

I tutorialspoint.com. Ruby on Rails Tutorial. url:http://www.tutorialspoint.com/ruby-on-rails/.

Dr inż. Stanisław Polak 234

Framework Ruby on Rails Źródła

Źródła II

I Wikipedia. Kurs PHP. url: http://pl.wikibooks.org/wiki/PHP.

I Wikipedia. Kurs Ruby. url: http://pl.wikibooks.org/wiki/Ruby.

I Wikipedia. url: http://pl.wikipedia.org/.

Dr inż. Stanisław Polak 235

Notatki

Notatki