SlideShare ist ein Scribd-Unternehmen logo
1 von 71
Beginner’s Sinatra
                                Minimal Framework in Ruby




2012/09/22 - kanazawa.rb #2
Web System

   Web server



Application server



Database server
Web System
                     Client
   Web server



Application server



Database server
example
Web System

  Apache



Tomcat (java)



 PostgreSQL
example
Web System

    nginx



 Rails (Ruby)



   MySQL
example
Web System

     thin



Sinatra (Ruby)



   MySQL
example
Web System

     thin



Sinatra (Ruby)



   MySQL
Sinatra
Sinatra

http://www.sinatrarb.com
Sinatra

http://www.sinatrarb.com



        Sinatra is a DSL for
          quickly creating
     web applications in Ruby
Sinatra

http://www.sinatrarb.com



        Sinatra is a DSL for
         quickly creating
     web applications in Ruby
Hello world!


$ gem install sinatra

$ vi myapp.rb

$ ruby myapp.rb
Hello world!


$ gem install sinatra

$ vi myapp.rb

$ ruby myapp.rb
Hello world!

require 'sinatra'


get '/' do
 'Hello world!'
end
Hello world!

require 'sinatra'


get '/' do
 'Hello world!'
end
                    that's all
Hello world!

require 'sinatra'


get '/' do
 'Hello world!'
end
Hello world!

          require 'sinatra'
Request

          get '/' do
           'Hello world!'
          end
Hello world!

          require 'sinatra'
Request

          get '/' do
           'Hello world!'
          end          Handling & Response
Hello world!


$ gem install sinatra

$ vi myapp.rb

$ ruby myapp.rb
Hello world!
Hello world!
MVC



Model
View
Controller
MVC



Model
View
Controller
MVC



Model
View           Sinatra
Controller
MVC



Model
View
Controller
MVC

               ActiveRecord
               DataMapper
                  Sequel
Model
View
Controller
MVC

               ActiveRecord
               DataMapper
                  Sequel
Model
View
                     erb
Controller          haml
                   Builder
MVC

                ActiveRecord
                DataMapper
                   Sequel
Model
View
                     erb
Controller          haml
                   Builder


        As you like :)
Sinatra

Minimal “Routing” Framework in Ruby



            handling     response

request     handling     response

            handling     response
Routing
How to routing


1.HTTP method + URL path
2.Conditions
3.Filters
4.Passing
5.Halt & Error
1. HTTP method + URL path


HTTP method
  get
  post
  put
  delete
1. HTTP method + URL path

get '/' do ...

post '/' do ...

put '/' do ...

delete '/' do ...
                     first match
1. HTTP method + URL path



URL path
  pattern
  regular expressions
1. HTTP method + URL path

get '/path/' do ... # => '/path/'

get '/path/:dir/:file' do ... # => '/path/hoge/fuga'

get '/path/*.*' do ... # => '/path/hoge.xml'

get %r{/path/[w]+} do ... # => '/path/hoge'
                                           first match
2. Conditions


user agent
host name
mime type (≒HTTP Accept)
custom conditions
2. Conditions


get '/', :agent => /MSIE/ do ...

get '/', :host_name => /^admin./ do ...

get '/', :provides => :rss do ...

                                           first match
2. Conditions


set(:random) { |val| condition { rand <= val } }


get '/', :random => 0.2 do ... # => 20%
get '/' do ... # => 80%

                                          first match
3. Filters



Before
After
3. Filters


before '/usr/*' do ...
before '/' do ...
get '/usr/*' do ...
get '*' do ...
after '/usr/*' do ...
after do ... # => after '*' do ...
3. Filters

                                 /usr/hoge

before '/usr/*' do ...
before '/' do ...
get '/usr/*' do ...
get '*' do ...
after '/usr/*' do ...
after do ... # => after '*' do ...
3. Filters

                                 /usr/hoge

before '/usr/*' do ...               1
before '/' do ...
get '/usr/*' do ...                  2
get '*' do ...
after '/usr/*' do ...                3
after do ... # => after '*' do ...
3. Filters

                                 /usr/hoge   /

before '/usr/*' do ...               1
before '/' do ...
get '/usr/*' do ...                  2
get '*' do ...
after '/usr/*' do ...                3
after do ... # => after '*' do ...
3. Filters

                                 /usr/hoge   /

before '/usr/*' do ...               1
before '/' do ...                            1
get '/usr/*' do ...                  2
get '*' do ...                               2
after '/usr/*' do ...                3
after do ... # => after '*' do ...           3
3. Filters

                                 /usr/hoge   /   /fuga

before '/usr/*' do ...               1
before '/' do ...                            1
get '/usr/*' do ...                  2
get '*' do ...                               2
after '/usr/*' do ...                3
after do ... # => after '*' do ...           3
3. Filters

                                 /usr/hoge   /   /fuga

before '/usr/*' do ...               1
before '/' do ...                            1
get '/usr/*' do ...                  2
get '*' do ...                               2    1
after '/usr/*' do ...                3
after do ... # => after '*' do ...           3    2
4. Passing

get '*' do
  pass if rand <= 0.2;
  # xxx
end
get '*' do
  # xxx
end
                                 first match
4. Passing

get '*' do
  pass if rand <= 0.2;
  # xxx
end
get '*' do
  # xxx
end
                                 first match
5. Halt & Error


error 403 do
  'Access Forbidden'
end
before '/secret/*' do
  halt 403 unless authorized
end
5. Halt & Error


error 403 do
  'Access Forbidden'
end
before '/secret/*' do
  halt 403 unless authorized
end
5. Halt & Error


error 404 do
  'File Not Found'
end
before '/devel/*' do
  halt 'xxx'
end
Request
URL pattern (:xxx)



get '/path/:dir/:file' do # => '/path/hoge/fuga'
  params[:dir] # => "hoge"
  params[:file] # => "fuga"
end
URL pattern (*)

get '/path/*.*' do # => '/path/hoge/fuga.xml'
  params[:splat] # => [ "hoge/fuga", "xml" ]
end
get '/path/*.*' do |path, ext| # => '/path/hoge/fuga.xml'
  path # => "hoge/fuga"
  ext # => "xml"
end
URL regular expression


get %r{/path/([w]+)} do # => '/path/hoge'
  params[:capture] # => [ "hoge" ]
end
get %r{/path/([w]+)} do |cap| # => '/path/hoge'
  cap # => [ "hoge" ]
end
HTTP Get query


"/?abc=hoge&def=fuga"


get '*' do
  params[:abc] # => "hoge"
  params[:def] # => "fuga"
end
HTTP Post data

<input name="abc" value="hoge">
<input name="def" value="fuga">


post '*' do
  params[:abc] # => "hoge"
  params[:def] # => "fuga"
end
request object


get '*' do
  request.cookies # => cookie hash
  request.xhr? # => is ajax request (boolean)
  request.methods # => any more!
end
Response
Response type



1.Objects
2.Template
1. Object


String
Fixnum (as HTTP Status code)
Array
   [status (Fixnum), response body (responds to #each)]
   [status (Fixnum), headers (Hash), response body (responds to #each)]
2. Template

haml
erb
builder
2. Template

haml
erb
builder
sass
coffee-script
2. Template



get '/' do
 erb :index # => ./views/index.erb
end
2. Template



get '/' do
 erb :index # => ./views/index.erb
end
2. Template



get '/' do
 erb :index # => ./views/index.erb
end
                    config OK
2. Template

get '/' do
  @attr1 = "val1"
  @attr2 = "val2"
  erb :index
end


<%= @attr1 %><%= @attr2 %>
2. Template


get '/' do
  erb :index, :locals => { :attr1 => "val1", :attr2 => "val2" }
end




<%= attr1 %><%= attr2 %>
Conclusion
Sinatra


Minimal   routing framework

for   quickly creating web applications in Ruby

can using   any templates
Thank you




Tomokazu Kiyohara
http://facebook.com/tomokazu.kiyohara
http://twitter.com/kiyohara

Weitere ähnliche Inhalte

Was ist angesagt?

Using Sinatra as a lightweight web service
Using Sinatra as a lightweight web serviceUsing Sinatra as a lightweight web service
Using Sinatra as a lightweight web service
Gerred Dillon
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
Dave Cross
 
Pry, the good parts
Pry, the good partsPry, the good parts
Pry, the good parts
Conrad Irwin
 

Was ist angesagt? (20)

Chef Workshop: Setup Environment with Chef,Vagrant, and Berkshelf
Chef Workshop: Setup Environment with Chef,Vagrant, and BerkshelfChef Workshop: Setup Environment with Chef,Vagrant, and Berkshelf
Chef Workshop: Setup Environment with Chef,Vagrant, and Berkshelf
 
ES6 - Level up your JavaScript Skills
ES6 - Level up your JavaScript SkillsES6 - Level up your JavaScript Skills
ES6 - Level up your JavaScript Skills
 
Using Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsUsing Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python Projects
 
Intro to Rails
Intro to Rails Intro to Rails
Intro to Rails
 
Using Sinatra as a lightweight web service
Using Sinatra as a lightweight web serviceUsing Sinatra as a lightweight web service
Using Sinatra as a lightweight web service
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Moose - YAPC::NA 2012
Moose - YAPC::NA 2012Moose - YAPC::NA 2012
Moose - YAPC::NA 2012
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
Effective ES6
Effective ES6Effective ES6
Effective ES6
 
ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]
 
All That Jazz
All  That  JazzAll  That  Jazz
All That Jazz
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Ruby Kaigi 2008 LT
Ruby Kaigi 2008 LTRuby Kaigi 2008 LT
Ruby Kaigi 2008 LT
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
 
Bologna Developer Zone - About Kotlin
Bologna Developer Zone - About KotlinBologna Developer Zone - About Kotlin
Bologna Developer Zone - About Kotlin
 
Pry, the good parts
Pry, the good partsPry, the good parts
Pry, the good parts
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
Moose
MooseMoose
Moose
 

Andere mochten auch

Andere mochten auch (9)

Sinatraで鼻歌まじりのWeb開発
Sinatraで鼻歌まじりのWeb開発Sinatraで鼻歌まじりのWeb開発
Sinatraで鼻歌まじりのWeb開発
 
«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»«Работа с базами данных с использованием Sequel»
«Работа с базами данных с использованием Sequel»
 
Ruby object model
Ruby object modelRuby object model
Ruby object model
 
Advanced Ruby Idioms So Clean You Can Eat Off Of Them
Advanced Ruby Idioms So Clean You Can Eat Off Of ThemAdvanced Ruby Idioms So Clean You Can Eat Off Of Them
Advanced Ruby Idioms So Clean You Can Eat Off Of Them
 
Object-Oriented BDD w/ Cucumber by Matt van Horn
Object-Oriented BDD w/ Cucumber by Matt van HornObject-Oriented BDD w/ Cucumber by Matt van Horn
Object-Oriented BDD w/ Cucumber by Matt van Horn
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java Programmers
 
Ruby on Rails for beginners
Ruby on Rails for beginnersRuby on Rails for beginners
Ruby on Rails for beginners
 
How to Teach Yourself to Code
How to Teach Yourself to CodeHow to Teach Yourself to Code
How to Teach Yourself to Code
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java Developers
 

Ähnlich wie Beginner's Sinatra

Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
Yehuda Katz
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTful
goldoraf
 

Ähnlich wie Beginner's Sinatra (20)

Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
 
Swing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and SinatraSwing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and Sinatra
 
EC2
EC2EC2
EC2
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Monitoring web application behaviour with cucumber-nagios
Monitoring web application behaviour with cucumber-nagiosMonitoring web application behaviour with cucumber-nagios
Monitoring web application behaviour with cucumber-nagios
 
Mining Ruby Gem vulnerabilities for Fun and No Profit.
Mining Ruby Gem vulnerabilities for Fun and No Profit.Mining Ruby Gem vulnerabilities for Fun and No Profit.
Mining Ruby Gem vulnerabilities for Fun and No Profit.
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Rush, a shell that will yield to you
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to you
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Guarding Your Code Against Bugs with Continuous Testing
Guarding Your Code Against Bugs with Continuous TestingGuarding Your Code Against Bugs with Continuous Testing
Guarding Your Code Against Bugs with Continuous Testing
 
Paver For PyWorks 2008
Paver For PyWorks 2008Paver For PyWorks 2008
Paver For PyWorks 2008
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTful
 
Keeping It Small with Slim
Keeping It Small with SlimKeeping It Small with Slim
Keeping It Small with Slim
 

Mehr von Tomokazu Kiyohara

Mehr von Tomokazu Kiyohara (15)

JavaScript で OS X を自動操作
JavaScript で OS X を自動操作JavaScript で OS X を自動操作
JavaScript で OS X を自動操作
 
Google Cloud Platform を支える技術 …のごく一部
Google Cloud Platform を支える技術 …のごく一部Google Cloud Platform を支える技術 …のごく一部
Google Cloud Platform を支える技術 …のごく一部
 
イベント継続のコツ
イベント継続のコツイベント継続のコツ
イベント継続のコツ
 
Web API をデバックするときに必要なたったひとつのこと
Web API をデバックするときに必要なたったひとつのことWeb API をデバックするときに必要なたったひとつのこと
Web API をデバックするときに必要なたったひとつのこと
 
明日から使えるコーディングツール
明日から使えるコーディングツール明日から使えるコーディングツール
明日から使えるコーディングツール
 
Atom.io Quick Scripting
Atom.io Quick ScriptingAtom.io Quick Scripting
Atom.io Quick Scripting
 
Text-Objects - vim's elegant function
Text-Objects - vim's elegant functionText-Objects - vim's elegant function
Text-Objects - vim's elegant function
 
LiveStyle for Vim - Quick start
LiveStyle for Vim - Quick startLiveStyle for Vim - Quick start
LiveStyle for Vim - Quick start
 
こわくないプルリク
こわくないプルリクこわくないプルリク
こわくないプルリク
 
Github's HUB
Github's HUBGithub's HUB
Github's HUB
 
対サイバー攻撃アラートシステム “DAEDALUS”(ダイダロス)の紹介
対サイバー攻撃アラートシステム “DAEDALUS”(ダイダロス)の紹介対サイバー攻撃アラートシステム “DAEDALUS”(ダイダロス)の紹介
対サイバー攻撃アラートシステム “DAEDALUS”(ダイダロス)の紹介
 
Compact Web - Remind "web compression" -
Compact Web - Remind "web compression" -Compact Web - Remind "web compression" -
Compact Web - Remind "web compression" -
 
Zen coding15min
Zen coding15minZen coding15min
Zen coding15min
 
USTREAMの視聴率を上げよう!
USTREAMの視聴率を上げよう!USTREAMの視聴率を上げよう!
USTREAMの視聴率を上げよう!
 
JavaScript Dynamic Loading
JavaScript Dynamic LoadingJavaScript Dynamic Loading
JavaScript Dynamic Loading
 

Kürzlich hochgeladen

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Beginner's Sinatra

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n