├── .gitignore
├── .ruby-version
├── .travis.yml
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── TODO.md
├── bin
└── publish
├── config.rb
├── config.ru
├── data
├── book.yml
└── toc.yml
├── renumber.rb
└── source
├── 01-preface.md
├── 02-creation.md
├── 03-learning_to_program.md
├── 03-learning_to_program
├── 01-learning_modes.md
├── 02-dont_believe.md
├── 03-formatting_code.md
├── 04-error_messages.md
└── 05-using_google.md
├── 04-your_tools.md
├── 04-your_tools
├── 01-text_editor.md
├── 02-terminal.md
├── 03-ruby_runtime.md
├── 04-workflow.md
└── 05-irb.md
├── 05-roadmap.md
├── 06-object_oriented_programming.md
├── 07-variables.md
├── 07-variables
├── 01-reusing_names.md
└── 02-right_goes_first.md
├── 08-built_in_classes.md
├── 08-built_in_classes
├── 01-numbers.md
├── 02-strings.md
├── 03-true_false_nil.md
├── 04-symbols.md
├── 05-arrays.md
└── 06-hashes.md
├── 09-objects.md
├── 09-objects
├── 01-classes.md
├── 02-instances.md
├── 03-methods.md
├── 04-calling.md
├── 05-arguments.md
├── 06-listing.md
├── 07-predicates.md
├── 08-bangs.md
├── 09-class_methods.md
└── 20-notes.md
├── 10-writing_methods.md
├── 10-writing_methods
├── 01-constituents.md
├── 02-definition.md
├── 03-usage.md
├── 04-return_values.md
├── 05-scopes.md
├── 06-combining.md
├── 07-printing.md
└── 20-control_flow.md
├── 11-writing_classes.md
├── 11-writing_classes
├── 01-definition.md
├── 02-methods.md
├── 03-initializers.md
├── 04-instance_variables.md
├── 05-attribute_readers.md
├── 06-attribute_writers.md
├── 07-state_and_behaviour.md
├── 08-interaction.md
└── 09-self.md
├── 13-blocks.md
├── 13-blocks
├── 01-syntax.md
├── 02-arguments.md
├── 03-return_values.md
├── 04-ioc.md
├── 05-iterators.md
└── 10-methods_using_blocks.md
├── 14-conditionals.md
├── 14-conditionals
├── 01-shorthand.md
├── 02-return_values.md
└── 05-nothing_and_truth.md
├── 15-operators.md
├── 15-operators
├── 01-arithmetical.md
├── 02-logical.md
├── 03-comparison.md
└── 04-methods.md
├── 70-bonus.md
├── 70-bonus
├── 00-string_interpolation.md
├── 01-top_level.md
├── 03-other_methods.md
├── 04-questions_commands.md
├── 10-alternative-syntax.md
├── 11-good_names.md
├── 12-write_new_method.md
├── 13-arguments_parameters.md
└── 14-parentheses.md
├── 80-advanced.md
├── 80-advanced
├── 01-libraries.md
├── 02-modules.md
├── 03-private_methods.md
├── 04-procs.md
├── 05-yield.md
└── 06-regular_expressions.md
├── 90-exercises.md
├── 90-exercises
├── 01-numbers.md
├── 02-strings.md
├── 03-arrays_1.md
├── 04-hashes_1.md
├── 05-methods_1.md
├── 06-arrays_2.md
├── 07-nested_arrays.md
├── 08-hashes_2.md
├── 09-truthiness.md
├── 10-email.md
├── 11-mailbox.md
├── 12-mailbox_text.md
├── 13-mailbox_html.md
├── 14-mailbox_file.md
└── 15-mailbox_csv.md
├── 91-exercises_2.md
├── 91-exercises_2
├── 01-numbers.md
├── 02-strings.md
├── 03-arrays_1.md
├── 04-hashes_1.md
└── 99-notes.md
├── CNAME
├── assets
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ └── fontawesome-webfont.woff
├── images
│ └── favicon.png
├── javascripts
│ ├── modernizr.js
│ └── monstas.js
└── stylesheets
│ ├── _fonts.scss
│ ├── _html5-reset.css
│ ├── _layout.scss
│ ├── _print.scss
│ ├── _response.scss
│ ├── _style.scss
│ ├── monstas.scss
│ └── syntax.css.erb
├── index.md
├── layouts
└── layout.erb
├── print.erb
├── robots.txt
├── sitemap.xml.erb
├── solutions
├── 02-strings-3.html.md
├── 02-strings-4.html.md
├── 02-strings-5.html.md
├── 02-strings-6.html.md
├── 03-arrays_1-1.html.md
├── 03-arrays_1-2.html.md
├── 03-arrays_1-3.html.md
├── 03-arrays_1-4.html.md
├── 03-arrays_1-5.html.md
├── 04-hashes_1-1.html.md
├── 04-hashes_1-2.html.md
├── 04-hashes_1-3.html.md
├── 04-hashes_1-4.html.md
├── 04-hashes_1-5.html.md
├── 05-methods-1.html.md
├── 05-methods-2.html.md
├── 05-methods-3.html.md
├── 05-methods-4.html.md
├── 06-arrays_2-1.html.md
├── 06-arrays_2-2.html.md
├── 06-arrays_2-3.html.md
├── 06-arrays_2-4.html.md
├── 06-arrays_2-5.html.md
├── 06-arrays_2-6.html.md
├── 06-arrays_2-7.html.md
├── 07-nested_arrays-1.html.md
├── 07-nested_arrays-2.html.md
├── 08-hashes_2-1.html.md
├── 08-hashes_2-2.html.md
├── 08-hashes_2-3.html.md
├── 08-hashes_2-4.html.md
├── 09-truthiness-1.html.md
├── 09-truthiness-2.html.md
├── 10-email-1.html.md
├── 10-email-2.html.md
├── 11-mailbox-1.html.md
├── 12-mailbox_text-1.html.md
├── 13-mailbox_html-1.html.md
├── 14-mailbox_file-1.html.md
└── 15-mailbox_csv-1.html.md
└── solutions_2
├── 01-numbers-5.html
├── 02-strings-1.html.md
├── 02-strings-3.html.md
├── 02-strings-4.html.md
├── 03-arrays_1-1.html.md
├── 03-arrays_1-2.html.md
├── 03-arrays_1-3.html.md
├── 03-arrays_1-4.html.md
├── 03-arrays_1-5.html.md
├── 03-arrays_1-6.html.md
├── 03-arrays_1-7.html.md
├── 04-hashes_1-1.html.md
├── 04-hashes_1-2.html.md
├── 04-hashes_1-3.html.md
├── 04-hashes_1-4.html.md
├── 04-hashes_1-5.html.md
├── 05-methods-1.html.md
├── 05-methods-2.html.md
├── 05-methods-3.html.md
├── 05-methods-4.html.md
├── 06-arrays_2-1.html.md
├── 06-arrays_2-2.html.md
├── 06-arrays_2-3.html.md
├── 06-arrays_2-4.html.md
├── 06-arrays_2-5.html.md
├── 06-arrays_2-6.html.md
├── 06-arrays_2-7.html.md
├── 07-nested_arrays-1.html.md
├── 07-nested_arrays-2.html.md
├── 08-hashes_2-1.html.md
├── 08-hashes_2-2.html.md
├── 08-hashes_2-3.html.md
├── 08-hashes_2-4.html.md
├── 09-truthiness-1.html.md
├── 09-truthiness-2.html.md
├── 10-email-1.html.md
├── 10-email-2.html.md
├── 11-mailbox-1.html.md
├── 12-mailbox_text-1.html.md
├── 13-mailbox_html-1.html.md
├── 14-mailbox_file-1.html.md
└── 15-mailbox_csv-1.html.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | vendor/bundle
3 | build
4 | .sass-cache
5 | .DS_Store
6 | numbers.rb
7 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.2.1
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 |
3 | script: ./bin/publish
4 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'middleman', '3.3.7'
4 | gem 'middleman-syntax', '2.0.0'
5 | gem 'middleman-toc'
6 | # gem 'middleman-livereload'
7 | gem 'redcarpet'
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ruby For Beginners
2 |
3 | *Ruby Monday Study Group curriculum for beginners*
4 |
5 | You can [read it online here](http://ruby-for-beginners.rubymonstas.org).
6 |
7 | This book is built using [middleman](http://middlemanapp.com).
8 |
9 | The source code is kept on the main branch. The `build` directory is
10 | `.gitignore`d and should be initialized with another git repository so it can
11 | be pushed to the `gh-pages` branch in order to deploy changes to the site.
12 |
13 | After making changes, once you've committed them, you can publish your
14 | changes to the website using:
15 |
16 | ```
17 | ./bin/publish
18 | ```
19 |
20 | License: Creative Commons Attribution-ShareAlike
21 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | CHAPTERS = FileList[
2 | 'source/**/*.md'
3 | ]
4 |
5 | file 'ruby-for-beginners.pdf' => CHAPTERS do
6 | sh <<-CMD
7 | pandoc --toc --toc-depth=2 --latex-engine=xelatex -V documentclass=report -o ruby-for-beginners.pdf #{CHAPTERS}
8 | CMD
9 | end
10 |
11 | file 'ruby-for-beginners.epub' => CHAPTERS do
12 | sh <<-CMD
13 | pandoc --toc --toc-depth=2 -S --epub-metadata=data/book.yml -o ruby-for-beginners.epub #{CHAPTERS}
14 | CMD
15 | end
16 |
17 | task pdf: %W{ ruby-for-beginners.pdf }
18 | task epub: %W{ ruby-for-beginners.epub }
19 |
20 | task default: %W{ pdf epub }
21 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | An incomplete list of what's missing:
2 |
3 | * Check and re-think the order of topics. Some are Ruby language basics, some are
4 | tips and advice about tooling, searching, and general reflections on
5 | programming. We used about the same order of language basics, but then just
6 | anecdotally threw in other topics. I'm not sure how to best structure this
7 | in a book-style online resource.
8 | * Add more exercises, link to additional external exercises.
9 | * Add more topics that walk through the rest of the beginners curriculum, like
10 | writing to a file, using ERB to render a static HTML file, basics of HTTP,
11 | and building a Sinatra app that serves the same HTML.
12 | * Add a chapter about Ruby (e.g. optimized for happiness)
13 | * Add editor tips (shortcuts, syntax highlighting)
14 | * Add most common exception messages
15 | * Add a chapter about testing
16 |
17 | Notes:
18 |
19 | * Mention comments
20 | * Mention omitting curly braces for hashes on method calls
21 | * Bonus: calling methods is also referred as "sending messages", the method `send`
22 | * Bonus: default arguments
23 | * Bonus: splat operator for assignment and arguments
24 |
25 | Preface: Explain how the curriculum works (major milestones). Explain in more
26 | detail that everyone's supposed to go at their own pace, and not doing homework
27 | is completely acceptable.
28 |
29 | If local scopes are like rooms in a house, then instance variables are visible
30 | in every room in the house.
31 |
32 |
33 | In the chapter 02-creation talk about:
34 |
35 | * Writing code is creative. It is close to art, design, architecture and philosophy.
36 | * Heidegger: "language is the house of being"
37 | * all you need is a computer, internet connection and time
38 | * Building fun applications, or useful little tools (Debbie's lunch roulette)
39 |
40 | *I believe people want to express themselves when they program. They don’t want to fight with the language. Programming languages must feel natural to
41 | programmers. I tried to make people enjoy programming and concentrate on the
42 | fun and creative part of programming when they use Ruby.* - Yukihiro Matsumoto
43 | http://www.linuxdevcenter.com/pub/a/linux/2001/11/29/ruby.html
44 |
45 |
46 | Recommend to never copy and paste code, instead type it, and format it well.
47 |
48 | Move "String interpolation" up
49 |
--------------------------------------------------------------------------------
/bin/publish:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | git="git --git-dir=./build/.git --work-tree=./build"
6 |
7 | function run() {
8 | cmd=$@
9 | echo $cmd
10 | eval "$cmd"
11 | }
12 |
13 | function setup() {
14 | run "mkdir -p build"
15 | run "$git init"
16 | run "$git remote add origin git@github.com:rubymonsters/ruby-for-beginners.git"
17 | run "$git fetch"
18 | run "$git reset --hard origin/gh-pages"
19 | }
20 |
21 | function commit() {
22 | local msg=$1
23 | run "git add -A ."
24 | run "git commit -am '$msg' || true"
25 | run "git push"
26 | }
27 |
28 | function compile() {
29 | run "bundle exec middleman build --verbose"
30 | }
31 |
32 | function push() {
33 | run "$git add -A ."
34 | run "$git commit -am 'build'"
35 | run "$git push -f origin HEAD:gh-pages"
36 | }
37 |
38 | if [ ! -d build/.git ]; then
39 | setup
40 | fi
41 |
42 | if [ -n "$1" ]; then
43 | commit "$1"
44 | fi
45 |
46 | compile
47 | push
48 |
--------------------------------------------------------------------------------
/config.rb:
--------------------------------------------------------------------------------
1 | require 'middleman_toc'
2 |
3 | set :layouts_dir, '/layouts'
4 | set :css_dir, 'assets/stylesheets'
5 | set :js_dir, 'assets/javascripts'
6 | set :images_dir, 'images'
7 | set :source, 'source'
8 |
9 | page '/sitemap.xml', layout: false
10 | page '/solutions/*', :layout => false
11 | page '/solutions_2/*', :layout => false
12 |
13 | ignore(/themes\/(?!#{data.book.theme.downcase}).*/)
14 | config.ignored_sitemap_matchers[:layout] = proc { |file|
15 | file.start_with?(File.join(config.source, 'layout.')) || file.start_with?(File.join(config.source, 'layouts/')) || !!(file =~ /themes\/.*\/layouts\//)
16 | }
17 |
18 | activate :syntax
19 | set :markdown_engine, :redcarpet
20 | set :markdown, :fenced_code_blocks => true, :smartypants => true, :no_intra_emphasis => true, :autolink => true, :strikethrough => true, :tables => true
21 |
22 | set :relative_links, false
23 | activate :relative_assets
24 | activate :minify_css
25 | activate :minify_javascript
26 | activate :asset_hash
27 | activate :toc
28 |
29 | helpers do
30 | def discover_page_title(page = current_page)
31 | if page.data.title
32 | return page.data.title # Frontmatter title
33 | elsif page.url == '/'
34 | return data.book.title
35 | elsif match = page.render(layout: false, no_images: true).match(/(.*?)<\/h1>/)
36 | return match[1] + ' | ' + data.book.title
37 | else
38 | filename = page.url.split(/\//).last.gsub('%20', ' ').titleize
39 | return filename.chomp(File.extname(filename)) + ' | ' + data.book.title
40 | end
41 | end
42 |
43 | def link_to_if_exists(*args, &block)
44 | url = args[0]
45 |
46 | resource = sitemap.find_resource_by_path(url)
47 | if resource.nil?
48 | block.call
49 | else
50 | link_to(*args, &block)
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | run Middleman.server
2 |
--------------------------------------------------------------------------------
/data/book.yml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Ruby for Beginners
3 | author: Ruby Monstas
4 | github_url: https://github.com/ruby-monsters/learning_ruby
5 | domain: http://ruby-for-beginners.rubymonstas.org
6 | license_name: Attribution-ShareAlike
7 | license_url: https://creativecommons.org/licenses/by-sa/4.0
8 | theme: monstas
9 |
--------------------------------------------------------------------------------
/data/toc.yml:
--------------------------------------------------------------------------------
1 | - index
2 | - preface
3 | - creation
4 | - path: learning_to_program
5 | children:
6 | - learning_modes
7 | - dont_believe
8 | - formatting_code
9 | - error_messages
10 | - using_google
11 | - path: your_tools
12 | children:
13 | - text_editor
14 | - terminal
15 | - ruby_runtime
16 | - workflow
17 | - irb
18 | - roadmap
19 | - object_oriented_programming
20 | - path: variables
21 | children:
22 | - reusing_names
23 | - right_goes_first
24 | - path: built_in_classes
25 | children:
26 | - numbers
27 | - strings
28 | - true_false_nil
29 | - symbols
30 | - arrays
31 | - hashes
32 | - path: objects
33 | children:
34 | - classes
35 | - instances
36 | - methods
37 | - calling
38 | - arguments
39 | - listing
40 | - predicates
41 | - bangs
42 | - path: writing_methods
43 | children:
44 | - constituents
45 | - definition
46 | - usage
47 | - return_values
48 | - scopes
49 | - combining
50 | - printing
51 | - path: writing_classes
52 | children:
53 | - definition
54 | - methods
55 | - initializers
56 | - instance_variables
57 | - attribute_readers
58 | - attribute_writers
59 | - state_and_behaviour
60 | - interaction
61 | - self
62 | - path: blocks
63 | children:
64 | - syntax
65 | - arguments
66 | - return_values
67 | - ioc
68 | - iterators
69 | - path: conditionals
70 | children:
71 | - nothing_and_truth
72 | - path: operators
73 | children:
74 | - arithmetical
75 | - logical
76 | - comparison
77 | - methods
78 | - path: bonus
79 | children:
80 | - string_interpolation
81 | - top_level
82 | - other_methods
83 | - questions_commands
84 | - alternative-syntax
85 | - good_names
86 | - parentheses
87 | - arguments_parameters
88 | - write_new_method
89 | - path: advanced
90 | children:
91 | - libraries
92 | - modules
93 | - private_methods
94 | - procs
95 | - yield
96 | - regular_expressions
97 | - path: exercises
98 | children:
99 | - numbers
100 | - strings
101 | - arrays_1
102 | - hashes_1
103 | - methods_1
104 | - arrays_2
105 | - nested_arrays
106 | - hashes_2
107 | - truthiness
108 | - email
109 | - mailbox
110 | - mailbox_text
111 | - mailbox_html
112 | - mailbox_file
113 | - mailbox_csv
114 | - path: exercises_2
115 | children:
116 | - numbers
117 | - strings
118 | - arrays_1
119 | - hashes_1
120 |
--------------------------------------------------------------------------------
/source/02-creation.md:
--------------------------------------------------------------------------------
1 | # Programming is creation
2 |
3 | *Things coming to life*
4 |
5 | Programming is creation. Whenever you run a program a little universe is
6 | created. Things come to life and interact with each other, according to the
7 | rules that you, as their creator, define.
8 |
9 | Imagine you build an application like Twitter. Then, as a developer, in the
10 | programming language of your choice, you would say things like "Let there be
11 | users! And let there be tweets!", and once your application starts these things
12 | will come into existence. Next you would go ahead and define "Users can create
13 | tweets, and they can follow each other". And from now on, every time new users
14 | are created in the little universe that is your application, these users will
15 | have the ability to tweet and follow each other.
16 |
17 |
--------------------------------------------------------------------------------
/source/03-learning_to_program/01-learning_modes.md:
--------------------------------------------------------------------------------
1 | # Learning modes
2 |
3 | *People are different*
4 |
5 | Different people learn things in different ways.
6 |
7 | Some like to listen to lectures, or read books that thoroughly explain concepts
8 | before they then start exercising, and experiment with what they just learned.
9 | Others like to get their hands dirty, and play with code until it does what
10 | they want.
11 |
12 | Some want to fully understand what a certain line of code does, and why.
13 | Others don't care that much about the details, and want their code to produce
14 | the right things instead. They might memorize what worked, and understand things
15 | more fully later.
16 |
17 | Some understand concepts in logical ways, and go precisely by their definitions.
18 | Others understand things better by coming up with good analogies and metaphors.
19 | And yet others tend to simply memorize things and how they get used.
20 |
21 | Therefore there is no one true path or one-size-fits-all approach to learning
22 | programming. Try different things, and pay attention to what works well for you,
23 | what is the most fun to you, and keeps you motivated.
24 |
25 | If you find it hard to keep motivated working through a certain online tutorial,
26 | or if you have a hard time fully understanding what an exercise is about, then
27 | try to pick a different approach, or talk to your study group.
28 |
29 | Consider meeting with others during the week, have some coffee and cake and
30 | hang out, read some more of this book, or do a few exercises together.
31 |
32 | Also, consider joining local programming events, like meetups, hackdays, or a
33 | conference once in a while. That gives you a broader perspective, even if you
34 | might not be able to fully understand everything all the time. Meeting with
35 | others and hearing about their experiences can also be a good source for
36 | inspiration and motivation.
37 |
38 | If you can't put a lot of time into learning programming, then consider
39 | spending at least a few minutes on it every day. For example, every morning,
40 | before you leave the house, take 10 minutes to read a page in a programming
41 | book, review an exercise, or read some code. Or spend some time with it
42 | on the train on your way home from work later. This will keep your subconscious
43 | mind busy with programming concepts, and help you pick things up more easily
44 | later.
45 |
--------------------------------------------------------------------------------
/source/03-learning_to_program/04-error_messages.md:
--------------------------------------------------------------------------------
1 | # Reading error messages
2 |
3 | *Your new best friends*
4 |
5 | As programmers we want to build things that work. When we do exercises we want
6 | to figure out the solution to the given problem. Seeing error messages therefore
7 | has a negative connotation to it: we haven't managed to get it right! Right?
8 |
9 | Well, yes. But also, no. Errors can also indicate progress. Often error
10 | messages indicate that we've done the right first step, and now have to figure
11 | out the right next step.
12 |
13 | Whenever you find an error message printed on your terminal, don't fret.
14 | Instead, appreciate it. Read it carefully. Ruby is trying to give you a hand
15 | and help. Normally an error message tells you exactly what went wrong in your
16 | code, and where. Once you've understood what has happened look at your code and
17 | try to understand why it happened, and how you might fix it.
18 |
19 | Often, when you fix one thing, you'll get a different error message.
20 | That's progress. Rinse and repeat until your code does what you want.
21 |
22 | For a beginner, Ruby error messages can sometimes be hard to read. There are
23 | certain conventions used, e.g. for indicating there's an instance of
24 | a certain class involved. Backtraces might be hard to read and might look
25 | frightening. But all they do is tell you the exact path of execution Ruby
26 | took until it ended up raising an error.
27 |
28 | If you do not understand an error message and you have the opportunity to
29 | ask someone else, then do so. You'll get better and better at reading
30 | error messages over time. And you'll become friends with them.
31 |
--------------------------------------------------------------------------------
/source/03-learning_to_program/05-using_google.md:
--------------------------------------------------------------------------------
1 | # Using Google
2 |
3 | *Someone else has already had that question*
4 |
5 | Whenever you have a question, and you're not sure where to start looking for an
6 | answer, simply go ahead and ask Google. Some other person most probably has had
7 | the same question before, and often times you will find a helpful blog post,
8 | tutorial, documentation, or answer on community sites like Stack Overflow.
9 |
10 | Finding the right terms to type into Google might take some time. Experiment
11 | with this. If one question does not yield a helpful result on the first page,
12 | try to rephrase your question. You'll get better and better at this over time.
13 |
14 | Always include the keyword "ruby" though, so you don't get answers for other
15 | programming languages.
16 |
17 | E.g. if you are wondering if there is a method that gets you all the keys from
18 | a hash, then google for "ruby hash get keys". If you are wondering if there's
19 | a method to align strings so they all have a certain length, then google for
20 | "ruby string align".
21 |
22 | Google results that link to the Ruby documentation on ruby-doc.org are often
23 | good ones to look at, but these pages also often are very long. Look at the
24 | summary of the page on Google, and the highlighted terms, then go to the
25 | page and use your browser's search feature to find them on the page.
26 |
27 | Also, results on Stack Overflow are often very worthwhile to read. This is a
28 | programming community site where people with all kinds of experience levels
29 | post questions, which then will be answered by others. People can rank answers,
30 | and the best ranked answer appears at the top. Often it is worth skimming
31 | through most of the answers, as sometimes the question asked is just slightly
32 | different from yours, but someone might still suggest a solution that might be
33 | similar to the one you are looking for.
34 |
--------------------------------------------------------------------------------
/source/04-your_tools.md:
--------------------------------------------------------------------------------
1 | # Your tools
2 |
3 | When you start learning programming in Ruby you'll need three tools: A text
4 | editor, a terminal, and a Ruby runtime.
5 |
6 | As a programmer you'll spend tons of time working with your text editor and
7 | terminal (or "in" them, as we say). It makes sense for you to learn how to use
8 | these tools, and how to customize them so they fit your taste.
9 |
10 | There are also text editors that can be integrated into a terminal window. This
11 | means you don't have to switch between applications. There are also online
12 | services that integrate all of this as a web application, with a nice interface
13 | in your browser.
14 |
15 | Feel free to try all these things out, and play with them as much as you like.
16 | However, for our study groups, we have found that using the simplest tools
17 | possible, at least for a while, works best: It reduces the amount of things
18 | people need to learn in the beginning, and everyone learns the same few basic
19 | things that are required to run a Ruby program in this environment.
20 |
--------------------------------------------------------------------------------
/source/04-your_tools/01-text_editor.md:
--------------------------------------------------------------------------------
1 | # Text Editor
2 |
3 | For our study groups we recommend using [Sublime Text](http://www.sublimetext.com)
4 | as a text editor, which you can download and run on Mac OSX, Ubuntu, or
5 | Windows. This is an editor that has been specifically designed for writing
6 | code, comes with a lot of great tools, and can be easily customized.
7 |
8 | Other text editors that might be worth looking at are Atom, Textmate 2, and, if
9 | you like to use some of the powerful oldschool tools from the early times of
10 | Unix, VIM and Emacs. These are all great editors to use.
11 |
12 | Whatever editor you use, you want it to insert 2 spaces when you hit the "tab"
13 | key, i.e. when you want to indent your code. Make sure your editor is
14 | configured to do this.
15 |
16 | For Sublime Text you can do the following: In the menu item "Sublime Text" go
17 | to "Preferences" and select "Settings - User". This opens up a configuration
18 | file that you can edit just like any other file. Make sure it looks like this:
19 |
20 | ```json
21 | {
22 | "tab_size": 2,
23 | "translate_tabs_to_spaces": true
24 | }
25 | ```
26 |
27 | Also, we recommend enabling auto-saving your files. This will automatically
28 | save your changes when you switch to another application (like your terminal),
29 | and protect you from the mistake of forgetting to save:
30 |
31 | ```json
32 | {
33 | "tab_size": 2,
34 | "translate_tabs_to_spaces": true,
35 | "save_on_focus_lost": true
36 | }
37 | ```
38 |
39 | Whenever you open a new file, make sure to save it with a filename that ends
40 | with `.rb` first. This will tell the editor that you want this to be a Ruby
41 | file. Your editor will start highlighting your code as Ruby code, and enable other
42 | Ruby specific editor features. Alternatively, select "Ruby" in the extensions
43 | menu at the bottom right.
44 |
45 | Some keyboard shortcuts that are extremely useful to know are:
46 |
47 | * In order to indent or unindent a single, or multiple lines of code, select
48 | them and hit `tab` or `shift-tab` respectively.
49 | * In order to comment single, or multiple lines of code, select them, and
50 | hit `cmd-/` on Mac OSX, or `ctrl-/` on Linux/Windows.
51 | * Cut out code with `cmd-x`, copy code with `cmd-c`, and paste it with
52 | `cmd-v` on Mac OSX, on Linux/Windows use the `ctrl` key instead.
53 |
54 |
--------------------------------------------------------------------------------
/source/04-your_tools/02-terminal.md:
--------------------------------------------------------------------------------
1 | # Terminal
2 |
3 | Every operating system comes with some kind of terminal application built in,
4 | and they'll be fine to use for us.
5 |
6 | A terminal is an application that doesn't do much more but provide a window to
7 | run another program, called a "shell". A shell is a text-based program, so it
8 | does not have a window, and thus needs the terminal to be run on your graphical
9 | user interface.
10 |
11 | A shell is an interactive program that waits for you to type a command and hit
12 | enter (or "return"). It will then run the command, display any output, and
13 | then, again, sit and wait for you to type the next command.
14 |
15 | This is how working with computers was done in early times before there was the
16 | idea of a graphical user interface with clickable icons, windows, and a mouse as
17 | an input device. Instead, everything was done by typing commands.
18 |
19 | While this might take a little while for you to get used to, you'll discover
20 | why many programmers feel that working with the shell helps them be so much
21 | more productive and get simple things done so much quicker than using a mouse
22 | and a graphical interface.
23 |
24 | The default settings for most terminal applications that come built in to
25 | operating systems are quite poor, unfortunately. For example the Terminal.app
26 | on Mac OSX opens a tiny little mini window with a very small font. You want
27 | to make the window much (much!) bigger, and find the settings to pick
28 | a bigger font size. As a programmer, the terminal (along with your editor) is
29 | your new home. You want to be as comfortable reading and writing in your
30 | terminal as in any other application.
31 |
32 | In case you are using Microsoft Windows it is highly recommended to use any
33 | kind of unix based terminal. One option is Git-Bash (https://gitforwindows.org/).
34 | However, as Ruby and Microsoft Windows are not best friends, it is even better
35 | to install the Windows Subsystem for Linux which is available here for
36 | Windows 10: https://docs.microsoft.com/en-us/windows/wsl/install-win10. With
37 | this option you can install everything you need for your Ruby development
38 | under Ubuntu and use Bash as your main shell.
39 |
40 | All commands in the following texts are unix commands and will not work in a
41 | Microsoft Windows terminal.
42 |
43 | Once you have started the terminal program you will see your shell's prompt,
44 | and can start typing commands. You'll want to learn at least the command `cd`
45 | which allows you to navigate to a particular directory (where you have stored
46 | your code), and the command `ls` which lists the contents of a directory.
47 |
48 | Also learn how to use the command line completion using `tab`: For example,
49 | type `cd`, space, and the first two or so letters of the directory you want to
50 | navigate to, then hit `tab`. The shell will complete the rest of the directory
51 | name for you. If nothing happens, then there are multiple directory names
52 | starting with the same few letters. In this case hit `tab` twice, quickly,
53 | and your shell will display a list of choices. Type the next letter
54 | and hit `tab` again.
55 |
56 |
--------------------------------------------------------------------------------
/source/04-your_tools/03-ruby_runtime.md:
--------------------------------------------------------------------------------
1 | # Ruby runtime
2 |
3 | The last tool you need is a Ruby runtime. This is a program that can execute
4 | Ruby code, and it is a program that can be run in your shell (much like `cd`
5 | and `ls`).
6 |
7 | If you have some code in a file with the name `hello.rb`, and you have
8 | navigated to the directory where the file is saved, then you can type the
9 | following and hit enter, in order to execute the code:
10 |
11 | ```
12 | ruby hello.rb
13 | ```
14 |
15 | This will tell the `ruby` runtime to interpret the contents of the file
16 | `hello.rb` as Ruby code, and execute it.
17 |
18 | One can also use this program to do other things. You probably won't need
19 | these a lot, but we think it's good to know. You can try these by typing
20 | these commands in your terminal.
21 |
22 | E.g. you can print out the version of the program:
23 |
24 | ```
25 | ruby --version
26 | ```
27 |
28 | Or execute Ruby code without storing it to a file:
29 |
30 | ```
31 | ruby -e 'puts 123'
32 | ```
33 |
--------------------------------------------------------------------------------
/source/04-your_tools/04-workflow.md:
--------------------------------------------------------------------------------
1 | # Programming workflow
2 |
3 | In order to do programming excercises on your computer, play around with things
4 | you learned, and write actual, useful programs you want to learn the following
5 | workflow:
6 |
7 | * Write some code in your text editor.
8 | * Save the code to a file in a particular directory. The filename should end
9 | with `.rb`.
10 | * Open your terminal.
11 | * Navigate to that directory using `cd`.
12 | * Execute the file using `ruby`.
13 | * Switch back and forth between the text editor and terminal, so you
14 | can make small changes in your code, and then run it through `ruby` to see
15 | what it does.
16 |
17 | In order to switch back and forth between apps quickly you can use the keyboard
18 | shortcut `cmd-tab` on Mac OSX, and `alt-tab` on Ubuntu and Windows.
19 |
20 | In your shell you can use the `cursor up` key to go through your last used
21 | commands: you don't have to type `ruby hello.rb` again. Just hit `cursor up`
22 | and then enter to run it again.
23 |
24 |
--------------------------------------------------------------------------------
/source/04-your_tools/05-irb.md:
--------------------------------------------------------------------------------
1 | # Interactive Ruby
2 |
3 | One other tool that is worth mentioning, and that comes with your Ruby runtime,
4 | is `irb`. You can start it by typing `irb` in your shell and hitting enter.
5 |
6 | Its name is short for "Interactive Ruby Shell", and yes, it is another kind of
7 | shell: Just like the shell running in your terminal `irb` is also a program
8 | that interactively waits for you to type something, and hit enter. However,
9 | since this is a Ruby shell, it will expect that you type Ruby code instead of
10 | system commands.
11 |
12 | IRB is pretty handy for quickly trying something out, and it is a great tool
13 | for exploring the language Ruby, and things that come built in.
14 |
15 | For example:
16 |
17 | ```ruby
18 | $ irb
19 | > puts "Hello world!"
20 | Hello world!
21 | => nil
22 | >
23 | ```
24 |
25 | The first line starts the IRB program. Notice how the "prompt" indicator
26 | changes. The prompt will look a little different depending on your system and
27 | shell configuration, but often `$` is used to indicate that this is a
28 | system shell prompt, while `>` is used by IRB to indicate that this is an
29 | interactive Ruby shell.
30 |
31 | The second line is a piece of Ruby code. When you type this line and hit enter
32 | then Ruby will execute the code, and print out the text "Hello world!".
33 |
34 | It will then also print out the return value for this statement, which in this
35 | case is `nil`. This is something that you can simply ignore for the time being.
36 |
37 | On the last line you see IRB again waiting for input with a prompt.
38 |
39 | You can exit the IRB session, and get back to your system shell, by typing
40 | `exit` and hitting enter. Or you can also just hit `ctrl-d`, which does the
41 | same thing.
42 |
--------------------------------------------------------------------------------
/source/07-variables/01-reusing_names.md:
--------------------------------------------------------------------------------
1 | # Reusing variable names
2 |
3 | It is also important to keep in mind that a name is unique, in the sense that
4 | the same name can only be assigned to one value (object) at a time.
5 |
6 | In other words, if you assign different values to the same variable, then
7 | assignments that happen later will simply overwrite previous ones. Like so:
8 |
9 | ```ruby
10 | number = 4
11 | number = number * 3
12 | puts number + 2
13 | ```
14 |
15 | This, again, would output `14`.
16 |
17 |
18 | Variable names can be re-used, and re-assigned.
19 |
20 |
21 | The first line assigns the name `number` to the number `4`. The second line
22 | re-assigns it to another object.
23 |
24 | Getting back to our post-its metaphor ... this would stick a post-it with the
25 | name `number` on one thing, and then later take it off of it, and stick it on
26 | something else.
27 |
28 | Let's look at it under the microscope:
29 |
30 | * On the **first line** Ruby creates the number (object) `4`.
31 | * It then assigns the name `number` to it (sticks a post-it onto it).
32 | * On the **second line**, Ruby first looks at the stuff on the right side,
33 | and evaluates the expression `number * 3`. Doing so it will create
34 | the number (object) `3` and multiply it with the object that currently has
35 | the name `number`, which is `4`. This operation results in a new number
36 | (object) `12`.
37 | * Now Ruby is finally ready to stick the name `number` on the result `12`.
38 | I.e. *from now on* the name `number` refers to a different object, which is
39 | `12`.
40 | * On the **third line** Ruby will, again, first look at the expression `number + 2`
41 | on the right. It creates the object `2` and adds it to the object that currently
42 | has the name `number`. This results in a new number (object) `14`.
43 | * Finally Ruby passes this object `14` to `puts`, which outputs it to the
44 | screen.
45 |
46 | Of course, you would probably never actually write this exact code in practice
47 | since you can simply do all this in just one line instead: `puts 4 * 3 + 2`.
48 |
49 | However, sometimes you'll find or write code that assigns an initial value to a
50 | variable, and then keeps working on it for a few more lines. This sometimes is
51 | useful to break up long lines, and make code more readable.
52 |
53 |
54 | Using variable names can be useful to break up long lines and make code more
55 | expressive and readable.
56 |
57 |
58 | Also, Ruby has different kinds of variables.
59 |
60 | The kind of variable that we've introduced so far is called a *local variable*,
61 | and it's the one used most often. You will learn about another type of
62 | variables later when we talk about classes and objects.
63 |
64 |
65 | On formatting: Note that there are spaces around the assignment operator `=`
66 | as well as the arithmetical operators `+` and `*`.
67 |
68 |
69 |
--------------------------------------------------------------------------------
/source/07-variables/02-right_goes_first.md:
--------------------------------------------------------------------------------
1 | # Things on the right go first
2 |
3 | One last thing that is worth mentioning about variables:
4 |
5 | Just as in traffic (well, at least in
6 | [most parts of the world](https://en.wikipedia.org/wiki/Right-_and_left-hand_traffic)),
7 | things on the right side go first :)
8 |
9 | For a variable assignment, in order to assign the thing on the right side to
10 | the name on the left side, Ruby first needs to figure out the thing on the
11 | right. As you will see later the same is true for many other expressions in
12 | Ruby.
13 |
14 | In our example above it will first create the object that is the number `1`,
15 | and then assign it to the name `number`. The following example makes that more
16 | clear:
17 |
18 | ```ruby
19 | number = 2 + 3 * 4
20 | puts number
21 | ```
22 |
23 | When Ruby looks at the first line `number = 2 + 3 * 4` it notices that this is
24 | using the assignment operator `=`. Therefor, before it can assign the name
25 | `number` to the "thing" (object) on the right ... it first needs to know what
26 | that thing is.
27 |
28 | So, before she does anything else, Ruby will first look at the expression `2 +
29 | 3 * 4`, which will result in the number (object) `14`. She will *then* assign
30 | the name `number` to this object (i.e. evaluate the assignment operator `=`).
31 |
32 | You can imagine that in this moment, when Ruby starts evaluating the assignment
33 | `=` the code temporarily looks like this: `number = 14` (because the
34 | calculation has returned the number `14`).
35 |
36 | Does this make sense?
37 |
38 | Again, on the second line Ruby will then pass the thing with the name `number`
39 | (which is `14`) to `puts`, which will output it to the screen.
40 |
41 |
42 | Ruby evaluates the expression on the right first.
43 |
44 |
--------------------------------------------------------------------------------
/source/08-built_in_classes.md:
--------------------------------------------------------------------------------
1 | # Built-In Data Types
2 |
3 | As mentioned before, Ruby comes with lots of things already baked in, and
4 | provides you with tons of tools to use and hit the road running.
5 |
6 | We'll look at some of the most common data types in Ruby. Data types are types
7 | of "things" that are mainly used to represent data, such as numbers, text, and
8 | other values.
9 |
10 | This is basically the "stuff" that you, as a Ruby programmers will work with,
11 | when we work with actual data, that is interesting to you, or your users in one
12 | way or the other.
13 |
14 | We will discusss the following data types:
15 |
16 | * Numbers
17 | * Strings (texts)
18 | * True, False, and Nil
19 | * Symbols
20 | * Arrays
21 | * Hashes
22 |
23 | These "kinds of things" (objects) cover like 98% of all built-in data types
24 | that you'll be using on a day to day basis, i.e. these are being used all over
25 | the place. There are more data types, but those are rather exotic, and used
26 | much less often.
27 |
28 | Numbers and Strings (which is just a strange name for "texts") are some of the
29 | most basic "things" that you deal with in Ruby on a regular basis. The are also
30 | just enough lego bricks for us to dive into more interesting topics, such as
31 | how objects, classes, and methods relate to each other, and how you can create
32 | your own ones.
33 |
34 | Before we do so we will also briefly mention the "things" `true`, `false`, and
35 | `nil`, just because these are things that we'll come across along the way
36 | anyway.
37 |
38 | Symbols also are very commonly used, but quite an odd concept. You normally
39 | wouldn't need to understand Symbols in order to write your own code. We'll
40 | still cover them briefly, and use them once in a while, just in case you find
41 | them elsewhere.
42 |
43 | Arrays and Hashes are "things" (objects) that are used to store other things,
44 | and they're super useful, and widely used.
45 |
--------------------------------------------------------------------------------
/source/08-built_in_classes/01-numbers.md:
--------------------------------------------------------------------------------
1 | # Numbers
2 |
3 | Numbers are simply numbers.
4 |
5 | You can create one by writing it: `123` is Ruby code and it represents the
6 | number one-hundred-twenty-three.
7 |
8 | Negative numbers are created by prepending a minus `-`: This is the number
9 | minus-ninety-nine: `-99`.
10 |
11 | And of course there are decimal numbers, too. Again, you create one by writing
12 | it: `12.34`.
13 |
14 | You can also use an underscore to separate thousands places: E.g. `1_234.56` is the
15 | number one-thousand-two-hundred-thirty-four-point-five-six. However, this is
16 | optional. This is the exact same number in Ruby: `1234.56`.
17 |
18 |
19 | A number is defined by a series of digits, using a dot as a decimal mark, and
20 | optinally an underscore as a thousands separator.
21 |
22 |
23 | Note that different countries use different punctuation for decimal and
24 | thousands separators. Ruby is using the same notation used in the USA, which
25 | happens to be the exact opposite of what's used in Germany.
26 |
27 | ## Kinds of numbers
28 |
29 | Under the hood, for reasons that are mostly technical, there are actually
30 | different kinds of numbers:
31 |
32 | For example there are integer numbers (those without a fraction, i.e. a dot and
33 | decimal places), and depending on their size there are two kinds of them. For
34 | floating point numbers there are even more. Unless you are super curious, you
35 | can perfectly ignore all of that for now, and just think of numbers as numbers.
36 |
37 | However, when you do calculations with numbers, keep in mind that integer
38 | numbers ("integers") and decimal point numbers (floating point numbers, aka
39 | "floats") are different.
40 |
41 | If you do a calculation that uses integer number you'll always
42 | get an integer back:
43 |
44 | ```ruby
45 | $ irb
46 | > 1 + 2
47 | => 3
48 | ```
49 |
50 | However, if any of the numbers involved is a float, then you'll get a float back:
51 |
52 | ```ruby
53 | $ irb
54 | > 1.0 + 2
55 | => 3.0
56 | > 1 + 2.0
57 | => 3.0
58 | ```
59 |
60 |
61 | Mathematical operations result in a floating point number except if all numbers used are integer numbers.
62 |
63 |
64 | This is, for example, important when you do a division (`/` means "divide by"):
65 |
66 | ```ruby
67 | $ irb
68 | > 3 / 2
69 | => 1
70 | ```
71 |
72 | As you can see any decimal places will be just cut off, since the result needs
73 | to be an integer number.
74 |
75 | However, if you use floats:
76 |
77 | ```ruby
78 | $ irb
79 | > 3.0 / 2
80 | => 1.5
81 | > 3 / 2.0
82 | => 1.5
83 | ```
84 |
85 |
86 | Use floating point (decimal) numbers when doing devisions.
87 |
88 |
89 | Exercises: How about doing some of the [exercises on numbers](/exercises/numbers.html)
90 | next?
91 |
--------------------------------------------------------------------------------
/source/08-built_in_classes/03-true_false_nil.md:
--------------------------------------------------------------------------------
1 | # True, False, and Nil
2 |
3 | There are three more "things" that we'd like to mention quickly, just because
4 | you'll see quite frequently: These are `true`, `false`, and `nil`.
5 |
6 | The first two, `true` and `false` are just what you think they are:
7 |
8 |
9 | The object true represents "truth", while false
10 | represents the opposite of it.
11 |
12 |
13 | In other words, in Ruby, `true` and `false` are also "things", just like
14 | numbers, Strings, Arrays, and Hashes. You can assign them to variables, pass
15 | them around, and otherwise use them. They're fairly simple things, but they're
16 | also very useful.
17 |
18 | The third object `nil` represents "nothing". Yeah, that's right. In Ruby
19 | there's a "thing" that represents the absence of things. This might be a
20 | interesting topic to discuss on a philosophical level, but for now we'll
21 | just see how it works in Ruby.
22 |
23 |
24 | The object nil represents "nothing".
25 |
26 |
27 | You'll see later that every operation ("method") in Ruby always returns
28 | exactly one thing (i.e. one object), and that's why there needs to be a
29 | "thing" that represents "nothing".
30 |
31 | This will start to feel pretty natural to you pretty soon.
32 |
33 |
--------------------------------------------------------------------------------
/source/09-objects.md:
--------------------------------------------------------------------------------
1 | # Objects, Classes, Methods
2 |
3 | We've talked about objects quite a bit now, merely *using* that term as a
4 | synomym for "things". You've learned to do stuff with simple objects such as
5 | numbers and Strings, and the data structures Arrays and Hashes. You've also
6 | learned what a method is, how to define and use them, and how to pass things to
7 | them, and get others back.
8 |
9 | We're also prepared well enough to have a closer look at objects, classes
10 | (types of things) and methods, and how they relate to each other.
11 |
12 | As a sidenote, you may have heard the following. Rubyist love saying it:
13 |
14 |
15 | In Ruby everything is an object.
16 |
17 |
18 | Actually, this is a little bit of a lie. Even though it's being said so often,
19 | it isn't completely true: not *everything* is an object. There are a few things
20 | that are not objects.
21 |
22 | But almost everything is, and that's good enough to know for now.
23 |
24 |
25 | In Ruby almost everything is an object :)
26 |
27 |
28 | (Just in case you want to out-smart people at your local Ruby user group
29 | though, remember to ask "Really? Is an [if](conditionals.html) statement an
30 | object or a method? How about [self](/writing_classes/self.html)?")
31 |
--------------------------------------------------------------------------------
/source/09-objects/01-classes.md:
--------------------------------------------------------------------------------
1 | # Objects have classes
2 |
3 | As mentioned [before](/object_oriented_programming.html) when you run a Ruby
4 | program a little universe (space, scope) is being created, and populated with
5 | concrete objects (things) as defined by your program. These things interact,
6 | and do useful stuff, using certain methods that you call.
7 |
8 | Also, each concrete thing (object) is an instance of a general idea or type,
9 | and these ideas are called *classes*.
10 |
11 | You can see that objects have classes when you open IRB in your terminal and
12 | ask an object for its class:
13 |
14 | ```ruby
15 | $ irb
16 | > "this is a string".class
17 | => String
18 | ```
19 |
20 |
21 | Objects are concrete instances (manifestations) of classes.
22 |
23 |
24 | That means that the following sentence is true: In Ruby, `"a string"` *is a*
25 | `String`.
26 |
27 | Hmmmm, yeah, we kinda knew that already, right. However, you can also ask the
28 | same question in Ruby:
29 |
30 | ```ruby
31 | $ irb
32 | > "this is a string".is_a?(String)
33 | => true
34 | ```
35 |
36 | So, the actual string knows that it *is a* `String`, which in Ruby means that
37 | it is an instance of the class `String`. You can do this for any object. E.g.
38 | `1.is_a?(Numeric)`, also returns `true`. This is pretty cool.
39 |
40 | We also say that an object is an *instance* of its class. Let's see what that
41 | means.
42 |
43 |
--------------------------------------------------------------------------------
/source/09-objects/02-instances.md:
--------------------------------------------------------------------------------
1 | # Classes create objects
2 |
3 | *Objects are instances of classes.*
4 |
5 | Classes are kind of blue prints for the concrete objects. Every time a concrete
6 | object (such as the String `"one string"`, the String `"another string"`, the
7 | String `"yet another string"`, and so on ...) is created:
8 |
9 | We say that the class is *instantiated*: an object is created from it.
10 |
11 | What does that mean?
12 |
13 | Classes have a bunch of characteristics, but most importantly, every class
14 | defines a number of methods, which are specific to this type of thing (e.g. a
15 | String).
16 |
17 | Now, every time a new object is created ("instantiated") from this class this
18 | new object get ("inherits") all of these methods.
19 |
20 |
21 | Objects inherit methods from their classes.
22 |
23 |
24 | That's right. Objects have their own methods attached to them.
25 |
26 | We'll explain more about methods that belong to objects in the next chapter.
27 | And you'll see how you can define methods to your own classes, so they're then
28 | available on your objects when we start defining our
29 | [first, own class](/writing_classes).
30 |
31 | But for now we can already point out that all concrete Strings that you use in
32 | your code will all have the same methods defined (attached to them) ... because
33 | they're all created (instantiated) from the the same class.
34 |
35 | You can have a look at all the methods that the class `String` defines on
36 | Ruby's [documentation page](http://ruby-doc.org/core-2.2.0/String.html) for this
37 | class.
38 |
39 | Let's see how we can use these methods.
40 |
41 |
--------------------------------------------------------------------------------
/source/09-objects/03-methods.md:
--------------------------------------------------------------------------------
1 | # Objects have methods
2 |
3 | *Methods are an object's behaviour*
4 |
5 | Objects have methods, allowing us to do interesting stuff with them. An
6 | object's methods are things that the object can *do*.
7 |
8 | Think about a person, like, a friend of yours. You can ask this person for
9 | their name (call a method), and they'll tell you (return it to you). Their name
10 | is a piece of knowledge that this person has, and the ability to tell it to you
11 | (respond to your question) is a piece of behaviour (a method) they have.
12 |
13 | We could also ask them to make, and bring a cup of tea for us. Or we could ask
14 | them to remember a phone number, or email password.
15 |
16 | As Rubyists we actually say that we "talk to objects", or "send messages" to
17 | them: We do so by using (calling) methods that they respond to.
18 |
19 | So, what can an object do?
20 |
21 | That depends on their class (type). Numbers can do things that are useful for
22 | numbers, obviously. You can do math, and ask them about their mathematical
23 | properties (e.g. "Are you an odd number?"). Strings (text) come with way more
24 | methods, and they're often related to text transformations.
25 |
26 |
27 | Methods add behaviour that is useful to have for a particular type of object.
28 |
29 |
30 | We've already used some methods in the previous chapters: E.g. `"hello".upcase`
31 | calls the method `upcase` on the String `"hello"`.
32 |
33 | Also, `class` and `is_a?` are methods defined on all objects in Ruby, and
34 | therefore also defined on the String `"a string"`: `"a string".is_a?(String)`
35 | answers with `true`.
36 |
37 |
38 | Some methods, such as class, is_a?, are defined on all objects.
39 |
40 |
41 | Let's move on to see how we can use (call) these methods though.
42 |
--------------------------------------------------------------------------------
/source/09-objects/04-calling.md:
--------------------------------------------------------------------------------
1 | # Calling methods
2 |
3 | In Ruby, methods that belong to (are defined on) objects can be used (called)
4 | by adding a dot, and then the method name, like so:
5 |
6 | ```ruby
7 | object.method
8 | ```
9 |
10 | That's like saying *Hey object, please do [method]*.
11 |
12 | Let's try that out in IRB.
13 |
14 | For example, the class `String` defines methods like `upcase` (*Give me an
15 | uppercase version of yours*), `downcase` (*What's the downcased version of
16 | yours*), and `length` (*Hey string, what's your length?*).
17 |
18 | Here's how we can call them:
19 |
20 | ```ruby
21 | $ irb
22 | > name = "Ruby Monstas"
23 | > name.upcase
24 | => "RUBY MONSTAS"
25 | > name.downcase
26 | => "ruby monstas"
27 | > name.length
28 | => 12
29 | ```
30 |
31 | And so on.
32 |
33 | In other words, you first address, or mention, the object that you want to talk
34 | to, and then, with the dot `.`, "send a message" to the object by specifying
35 | the method name. We also say: "you call the method upcase on the string".
36 |
37 |
38 | A dot is used to call a method on an object.
39 |
40 |
41 | Imagine the string `name` is a person you can talk to. You can ask questions by
42 | "sending a message" to them, and they'll respond by sending (returning)
43 | something back. The term "sending messages" actually is used instead of
44 | "calling a method" in programming, and specifically in Ruby.
45 |
46 | So, you can ask the string to hand you an "upcased" version of itself. And
47 | it responds by doing so. Or you can ask it for its length, and it responds
48 | by returning the number `12` to you.
49 |
50 | You can have a look at all the methods that the class `String` defines
51 | (responds to) on Ruby's
52 | [documentation page for this class](http://ruby-doc.org/core-2.2.0/String.html).
53 |
54 | Most methods in Ruby work this way: You ask an object to return a bit of
55 | information about itself (such as a String's length), or a modified
56 | (transformed) version of itself (such as a downcased version of the String).
57 |
58 |
59 | Most methods are questions, and return a relevant value.
60 |
61 |
62 | Others modify the object itself, and some have so called side-effects, and
63 | modify something else, e.g. `puts` and `p` both output something to the
64 | screen. Other methods might save files, send emails, or store things to
65 | a database.
66 |
67 |
68 | Some methods are commands, and change the object, or the system (e.g. by saving a file).
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/source/09-objects/05-arguments.md:
--------------------------------------------------------------------------------
1 | # Passing arguments
2 |
3 | *Extra information needed*
4 |
5 | Sometimes an object needs a
6 | little bit of extra information in order to do what you ask for.
7 |
8 | For example the class `String` defines the method `delete` which returns
9 | another String with some of the characters deleted. In order to do so, of
10 | course, it needs to know which characters we'd like to remove.
11 |
12 | We can pass things by appending parentheses `()` to the method call (the name).
13 | We can then include the extra bit of information needed (in our case another
14 | string) inside the parentheses like so:
15 |
16 | ```ruby
17 | $ irb
18 | > name = "Ruby Monstas"
19 | > name.delete("by Mo")
20 | => "Runstas"
21 | ```
22 |
23 | Hm. Not sure what "Runstas" means. Ideas? Let us know.
24 |
25 | Anyhow, another example for a method that needs an argument is the method
26 | `prepend` on Strings. This method returns a new String with the given String
27 | prepended:
28 |
29 | ```ruby
30 | > name = "Ruby Monstas"
31 | > name.prepend("Oh, hello, ")
32 | => "Oh, hello, Ruby Monstas"
33 | ```
34 |
35 | These extra bits of information are called *arguments*. We'll discuss them more
36 | once we get to define [our own methods](/writing_methods.html).
37 |
38 | Not all methods need these extra bits of information (arguments) in order to do
39 | their job. E.g. the method `length` on Strings knows the length of their
40 | String just so (because it knows its String). Sometimes they need one or more
41 | arguments though.
42 |
43 | So how do you know?
44 |
45 | You might remember, over time, for some important methods, but most of us also
46 | check the documentation quite frequently, too. Some times it's just fine to
47 | try it out quickly, and only check the documentation if it does not work as
48 | expected.
49 |
50 |
--------------------------------------------------------------------------------
/source/09-objects/06-listing.md:
--------------------------------------------------------------------------------
1 | # Listing methods
2 |
3 | As said above, if you are curious what methods are defined on a certain object,
4 | then you can check the [Ruby documentation](http://ruby-doc.org/core-2.2.0/)
5 | for this class. (Usually the right page conveniently shows up at the top when
6 | you google for "ruby" and the class name.)
7 |
8 | However, you can also quickly pop into IRB and ask the object for its methods.
9 | That's right, `methods` is a method defined on all objects (just like `class`,
10 | and `is_a?`).
11 |
12 | When you call it then it will return (respond with) an Array with all the
13 | method names that the object has.
14 |
15 | It makes sense to sort the Array, so it is easier to read. Like so:
16 |
17 | ```ruby
18 | $ irb
19 | > "Ruby Monstas".methods.sort
20 | => [:*, :+, :<, :>, :[], :class, :downcase, :delete, :include?, :is_a?, :length, :prepend, :start_with?]
21 | ```
22 |
23 | Yep, the method names come as Symbols, because they're considered code.
24 |
25 | If you do this yourself, you'll see that the String actually has a lot more
26 | methods. Many of these actually aren't used very often, but some are quite
27 | useful. We have stripped the Array down a little, because we want to talk about
28 | some of these methods more.
29 |
30 | ## Chaining method calls
31 |
32 | Btw the code above also demonstrates that methods can be "chained": When we
33 | call a method on an object it will return another object to us. We can then
34 | immediately call another method on that new object, and so on.
35 |
36 | In our example above the method `methods` returns a Array of names. And
37 | Arrays respond to (have) the method `sort`, so we can call this method
38 | immediately, by using another dot.
39 |
40 | We could chain some of the method calls from our String example above like so:
41 |
42 | ```ruby
43 | $ irb
44 | > name = "Ruby Monstas"
45 | > name.prepend("Oh, hello, ").upcase
46 | => "OH, HELLO, RUBY MONSTAS"
47 | ```
48 |
49 | So we have a String `"Ruby Monstas"`, prepend another String to it, which
50 | returns a new String `"Oh, hello, Ruby Monstas"`, on which we immediately call
51 | the method upcase.
52 |
53 | Pretty handy.
54 |
55 | As you can see Ruby will first evaluate the bit `name.prepend("Oh, hello, ")`.
56 | It needs to do that so it knows the object (the new String) that is going
57 | to be returned from this, so it can then call the method `upcase` on it.
58 |
59 | Does this make sense?
60 |
--------------------------------------------------------------------------------
/source/09-objects/07-predicates.md:
--------------------------------------------------------------------------------
1 | # Predicate methods
2 |
3 | If you check the list of methods on our String above you see that in Ruby we
4 | can have methods that end with a question mark `?`. What's up with that?
5 |
6 | By convention, in Ruby, these methods return either `true` or `false`. For
7 | example, we can ask a number if it is even or odd:
8 |
9 | ```ruby
10 | $ irb
11 | > 5.odd?
12 | => true
13 |
14 | > 5.even?
15 | => false
16 | ```
17 |
18 | This makes them read like a question, which is pretty cool.
19 |
20 | Or you can ask the number if it's between two other numbers. Obviously this
21 | methods needs us to pass those two other numbers. So now we also have an example
22 | of a method that takes two arguments:
23 |
24 | ```ruby
25 | > 5.between?(1, 10)
26 | => true
27 |
28 | > 5.between?(11, 20)
29 | => false
30 | ```
31 |
32 | These methods are called *predicate methods* in Ruby. Not quite sure why, maybe
33 | because of the historical math context of programming.
34 |
35 |
36 | Predicate methods that end with a question mark ? return either true or false.
37 |
38 |
39 | Strings also define some predicate methods:
40 |
41 | ```ruby
42 | > name = "Ruby Monstas"
43 | > name.start_with?("R")
44 | => true
45 | > name.start_with?("a")
46 | => false
47 | ```
48 |
49 | Do you also think it's kinda odd that `name.start_with?("a")` reads almost like
50 | English, but not quite? Maybe the method could have been named `starts_with?`
51 | instead, right? That's true. This is because Matz, the creator of Ruby, is not
52 | a native English speaker, and some names sound right in Japanese when
53 | translated literally.
54 |
55 | Also:
56 |
57 | ```ruby
58 | > name = "Ruby Monstas"
59 | > name.include?("by")
60 | => true
61 |
62 | > name.include?("r")
63 | => false
64 | ```
65 |
66 | When we check what methods there are defined on a number, we find some with the
67 | same name, but also different ones:
68 |
69 | ```ruby
70 | $ irb
71 | > 1.methods.sort
72 | => [:*, :+, :-, :/, :between?, :even?, :odd?, :zero?]
73 | ```
74 |
75 | Let's try `zero?`:
76 |
77 | ```ruby
78 | > 0.zero?
79 | => true
80 |
81 | > 1.zero?
82 | => false
83 | ```
84 |
85 | Arrays have the methods `include?`, and Hashes respond to `key?`:
86 |
87 | ```ruby
88 | > [1, 2].include?(1)
89 | => true
90 |
91 | > [1, 2].include?(3)
92 | => false
93 |
94 | > { "eins" => "one" }.key?("eins")
95 | => true
96 |
97 | > { "eins" => "one" }.key?("zwei")
98 | => false
99 | ```
100 |
101 | Oh by the way, if you're curious why operators like `*`, `+`, `-` and so on are
102 | also listed here, check the chapter that explains that [operators are methods,
103 | too](/operators/methods.html).
104 |
105 |
--------------------------------------------------------------------------------
/source/09-objects/08-bangs.md:
--------------------------------------------------------------------------------
1 | # Bang Methods
2 |
3 | All of the examples that we've discussed before have one thing in common:
4 |
5 | They are questions, and do not modify the object they are called on.
6 |
7 | For example:
8 |
9 | ```ruby
10 | name = "Ruby Monstas"
11 | puts name.downcase
12 | puts name
13 | ```
14 |
15 | This will output:
16 |
17 | ```ruby
18 | ruby monstas
19 | Ruby Monstas
20 | ```
21 |
22 | As you can see the method `downcase` has returned a new String, which is the
23 | lowercase version of the String that the method is being called on. When we
24 | output the original String on the next line, we can then see that it's still
25 | the same: The method `downcase` does not modify the String.
26 |
27 | However, there also are variants of some of these methods, which end in an
28 | exclamation mark `!`. These methods are called "bang methods", and they usually
29 | modify the object that they're being called on.
30 |
31 |
32 | Bang methods end with an exlamation mark, and often modify the object they are called on.
33 |
34 |
35 | For example, next to the method `downcase` Strings also have a method `downcase!`.
36 |
37 | Let's try that:
38 |
39 | ```ruby
40 | name = "Ruby Monstas"
41 | puts name.downcase!
42 | puts name
43 | ```
44 |
45 | This will output:
46 |
47 | ```ruby
48 | ruby monstas
49 | ruby monstas
50 | ```
51 |
52 | As you can see calling the method `downcase!` on the second line has modified
53 | the String itself (the object that `name` refers to), and *also* returned the
54 | new downcased version.
55 |
56 | Nowadays programmers have learned that using these methods has a number of
57 | disadvantages, and usually should be avoided, unless there are very good
58 | reasons for it (usually, there are none).
59 |
60 |
61 | Use bang methods with caution.
62 |
63 |
64 | We mostly mention these methods because you might see them used elsewhere.
65 |
--------------------------------------------------------------------------------
/source/09-objects/09-class_methods.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/09-objects/09-class_methods.md
--------------------------------------------------------------------------------
/source/09-objects/20-notes.md:
--------------------------------------------------------------------------------
1 |
2 |
53 |
54 |
--------------------------------------------------------------------------------
/source/10-writing_methods.md:
--------------------------------------------------------------------------------
1 | # Writing Methods
2 |
3 | *A named block of code that takes input and returns output*
4 |
5 | Everything in programming is about data, and doing interesting things with it.
6 | If you think about Twitter, it essentially takes 140 characters of text
7 | (which is data) from their users and displays it to others.
8 |
9 | You have already learned about the most important primitive (simple) types of
10 | data in Ruby: numbers, strings, true, false and nil. And we've had a look at
11 | the two most common data structures, Arrays and Hashes.
12 |
13 | All of this is about the *data* part. Methods on the other hand are about the
14 | *doing interesting things* part.
15 |
16 | In this chapter we'll have a closer look at the anatomy of a method, and you'll
17 | learn how to implement, and use, your own methods.
18 |
19 | ## Methods define behaviour
20 |
21 | Methods are all about defining *behaviour*, so that they can be applied to
22 | different bits of data in different contexts easily.
23 |
24 | For example, there are methods that do things like: transforming a String,
25 | sorting a list, reading a CSV or Excel file, sending an email, signing in to
26 | Facebook, sending a Tweet.
27 |
28 | Another way of putting this is: Methods are a way of assigning a name to a
29 | certain piece of code. Just like a variable allows to "look up" or refer to
30 | the object that the name was assigned to ... methods allow to execute their
31 | code.
32 |
33 |
34 | Variables name things, methods name behaviour (code).
35 |
36 |
37 | Methods make code re-usable, by the way of packaging ("encapsulating") code and
38 | sticking a name on it.
39 |
40 | As you have seen Ruby comes with lots of methods predefined - written by
41 | experienced programmers. So, unless you're studying computer science and you're
42 | faced with the exercise of implementing your own, complicated sorting
43 | algorithms for data collections, ... you'll just use the method `sort` that
44 | already comes defined for Arrays in Ruby out of the box.
45 |
46 | Ok, let's see what makes up a method, and how we can define our own ones.
47 |
48 |
--------------------------------------------------------------------------------
/source/10-writing_methods/01-constituents.md:
--------------------------------------------------------------------------------
1 | # What makes a method
2 |
3 | There are four things that constitute a method:
4 |
5 | * a name
6 | * a block of code
7 | * (optionally) accepting input
8 | * returning output
9 |
10 | Not all methods actually need input (so they don't take any), and not always do
11 | we care about the output that a method returns.
12 |
13 | Imagine a vending machine where you can chip in some money, press some buttons,
14 | and the machine will spin a few gears and wheels, and spit out the chocolate
15 | bar you were after.
16 |
17 | If the vending machine was a method, then your money, as well as the buttons
18 | you press are the *input*. The way the machine internally spins certain
19 | mechanics is the *block of code*, the stuff it does internally. And the product
20 | that it dispenses is the *return value*.
21 |
22 | Although this would be an odd thing to mention to a non-programmer, we could
23 | say that a vending machine is a way of "transforming" money and data into
24 | chocolate.
25 |
26 | Methods are a lot like that.
27 |
28 |
29 | Methods have a name, take some input, do something with it, and return a result.
30 |
31 |
32 | Programmers usually don't use the term "input" in this context. Instead we say
33 | that a method accepts a number of *arguments* (pieces of input). And instead of
34 | "output" we use the term *return value*: the thing that we get back from the
35 | method.
36 |
37 |
38 | A method's input is referred to as "arguments", while its output is called a
39 | "return value".
40 |
41 |
42 | This will become more clear in the following chapters. Let's define a method next.
43 |
--------------------------------------------------------------------------------
/source/10-writing_methods/02-definition.md:
--------------------------------------------------------------------------------
1 | # Defining a method
2 |
3 | So far you have seen methods that "belong" to objects, or, in other words,
4 | are defined on objects, and can be called on objects. E.g. you have seen the
5 | method `downcase` which is defined on every string.
6 |
7 | However, Ruby also knows methods that are not defined on any of these objects.
8 | They're sort of "stand alone" methods.
9 |
10 | For example, you can try this in `irb`:
11 |
12 | ```ruby
13 | $ irb
14 | > is_a?(Object)
15 | true
16 | ```
17 |
18 | We'll use this type of methods in this chapter because we want to focus on the
19 | characteristics of methods. If you're curious what's up with them have a look
20 | at the bonus chapter about the [top-level object](bonus/top_level.html). Later
21 | when you learn how to define your own classes we also look at defining methods
22 | for these.
23 |
24 | Ok, let's get started.
25 |
26 | Suppose we need to define a simple method that takes a number, adds the number
27 | `2` to it, and returns the result. Here's how we can do that:
28 |
29 | ```ruby
30 | def add_two(number)
31 | number + 2
32 | end
33 | ```
34 |
35 | This *defines* a method. It does not *use* it, yet: You only build and place
36 | that vending machine, so it can be used (by yourself, or others) later.
37 |
38 | Let's walk through this method definition step by step:
39 |
40 | Ruby will start reading the code at the top, and find the keyword `def`. This
41 | tells Ruby that we're about to define a new method.
42 |
43 | Methods need a name, so Ruby looks for it next, and finds the word `add_two`.
44 |
45 | Ruby then checks if we define anything to "input" to the method (remember, this
46 | is optional). She finds the parentheses, and knows that we're about to define
47 | a list of things that can be given to the method. This list is called an
48 | *argument list*.
49 |
50 |
51 | An argument list defines names for objects passed to the method, enclosed by
52 | parentheses right after the method name.
53 |
54 |
55 | In our case the argument list has one single argument `number`, which means
56 | our method can accept one single thing (object).
57 |
58 | The next line is the block of code that our method has ("encapsulates"). This
59 | is also referred to as the *method body*. In our case that's just one single
60 | line because the operation that our method encapsulates is very simple. Other
61 | methods (think of `sort`, defined on Arrays) would require more code, and are
62 | longer.
63 |
64 | Inside the method body the arguments are known as local variables: You can see
65 | how the code in our method body uses the variable name `number`.
66 |
67 | Finally the keyword `end` tells Ruby that we're done with the method body, and
68 | the method definition.
69 |
70 | All we've done so far is defining the method, we haven't used it for anything,
71 | yet. We'll do that in the next chapter.
72 |
73 |
74 | On formatting: Note that the keywords def and end sit
75 | on the same level, while the method body is indented by two spaces. Also, there
76 | are no space before or inside the argument list, i.e. the ()
77 | parentheses.
78 |
79 |
--------------------------------------------------------------------------------
/source/10-writing_methods/03-usage.md:
--------------------------------------------------------------------------------
1 | # Using (calling) a method
2 |
3 | Once defined we can use our method.
4 |
5 | As programmers we usually say that we "call" a method. This means we ask Ruby
6 | to execute the code that the method body has, with some given arguments
7 | (input), if any.
8 |
9 | Here's how that looks:
10 |
11 | ```ruby
12 | def add_two(number)
13 | number + 2
14 | end
15 |
16 | puts add_two(3)
17 | ```
18 |
19 | Let's inspect what's happening here under the microscope. If you don't
20 | understand each part of this just yet, don't worry, we'll get back to all of
21 | this.
22 |
23 | On the first three lines Ruby defines the method `add_two` as discussed above.
24 |
25 | * On the next line Ruby will look at the bit `add_two(3)` first. She recognizes
26 | that we are referring to a method defined earlier, and this will tell her we
27 | want to call (execute, use) this method.
28 | * In order to do so she first needs to look at what's inside the parantheses
29 | `()` so she can pass it on. She finds the `3` and creates a new object
30 | (number) for it.
31 | * Now Ruby is ready to actually call (execute, use) the method, passing the
32 | number `3`.
33 |
34 | So Ruby now deviates from the normal flow, which just goes from top to bottom
35 | in our file. Instead she now jumps into the method body.
36 |
37 | In this moment she now *assigns* the number `3` to a local variable `number`
38 | before she starts executing the method body.
39 |
40 | That's right. This is how method *arguments* work:
41 |
42 | When a method is called and objects are passed as arguments, then Ruby
43 | implicitely defines local variables with the argument names. She assigns the
44 | passed objects to the variable names that are in the argument list. These local
45 | variables are then available in the method body.
46 |
47 | In our case we have just one argument `number`. So we get one local variable
48 | `number` with the object `3` assigned (because that's the object passed when we
49 | called the method).
50 |
51 | You can imagine the method body now reads like this:
52 |
53 | ```ruby
54 | number = 3
55 | number + 2
56 | ```
57 |
58 | Ok, so we're inside the method body now:
59 |
60 | * Ruby will now execute (evaluate, run) the method body (again, going from top
61 | to bottom), which in our case is just a single line with the expression
62 | `number + 2`.
63 | * Because `number` is assigned `3` this expression will evaluate to `5`.
64 | * Since this line of code is the last line in the method body, the value `5`
65 | also is the value returned from the method call.
66 |
67 | So Ruby now jumps back out of the method. The expression `add_two(3)` has just
68 | returned the object `5`. Imagine the last line now reads like this instead:
69 |
70 | ```ruby
71 | puts 5
72 | ```
73 |
74 | And that will now print the number `5` to the screen.
75 |
76 | Let's have a closer look at that thing with the return value ("output"), as
77 | we just rushed over that a little.
78 |
--------------------------------------------------------------------------------
/source/10-writing_methods/04-return_values.md:
--------------------------------------------------------------------------------
1 | # Return values
2 |
3 | In Ruby, a method always return exactly one single thing (an object).
4 |
5 | The returned object can be anything, but a method can only return one thing,
6 | and it also *always returns something*.
7 |
8 |
9 | Every method always returns exactly one object.
10 |
11 |
12 | The object returned could be the object `nil`, meaning "nothing", but it still
13 | is an object. Also, in order to return a bunch of things at once we could
14 | return an Array that holds the things that we are interested in, but the Array
15 | itself is just one object.
16 |
17 | Also note that in Ruby we do not have to use the statement `return`, as in
18 | other languages. In fact, most Ruby code does not use the keyword `return` at
19 | all.
20 |
21 | This is extremely convenient, but it is also something we need to learn:
22 |
23 | If we don't do anything else, then a method will return *the value that was
24 | returned from the last evaluated statement*. Most often, this is the last line
25 | in the method body.
26 |
27 | This is important to understand. Please read that sentence again:
28 |
29 |
30 | If we don't do anything else, then a method will return the return value of
31 | the last evaluated statement.
32 |
33 |
34 | In our example method ...
35 |
36 | ```ruby
37 | def add_two(number)
38 | number + 2
39 | end
40 |
41 | p add_two(3)
42 | ```
43 |
44 | ... the last evaluated statement is the expression `number + 2`. Since in our
45 | example `number` is assigned `3` this expression returns the number `5`, and
46 | that is why the value returned by our method also is `5`.
47 |
48 | If, in certain cases, we do want to "return" from the method early, then we can
49 | still do this using the `return` statement. For now, you don't need to worry
50 | about this case.
51 |
52 | So, let's move on :)
53 |
--------------------------------------------------------------------------------
/source/10-writing_methods/06-combining.md:
--------------------------------------------------------------------------------
1 | # Combining Methods
2 |
3 | We've discussed how to define a method, and how to call (use) it.
4 |
5 | What if one method is not enough? What if methods need to do more complicated
6 | things?
7 |
8 | Easy. We can call methods from other methods.
9 |
10 | For example, we could re-write ("re-implement") our method `add_two` using
11 | another method `add_one`, and simply call it twice:
12 |
13 | ```ruby
14 | def add_one(number)
15 | number + 1
16 | end
17 |
18 | def add_two(number)
19 | number = add_one(number)
20 | add_one(number)
21 | end
22 |
23 | puts add_two(3)
24 | ```
25 |
26 | This would output `5` just like our previous examples. Do you understand how it
27 | works?
28 |
29 | Of course, in Ruby we could also just solve this whole thing with simply using
30 | the `+` operator.
31 |
32 | However, for the sake of the example, let's have a look how we could add a method
33 | that does the exact same thing as the `+` operator, too:
34 |
35 | ```ruby
36 | def sum(number, other)
37 | number + other
38 | end
39 | ```
40 |
41 | We can now use that method like so:
42 |
43 | ```ruby
44 | puts sum(3, 2)
45 | ```
46 |
47 | Which, again, would output `5`.
48 |
49 | Note that in this example our method `sum` now takes two arguments, and so,
50 | when we call (use) it, we also need to pass two numbers (i.e. add them inside
51 | the parentheses on the last line).
52 |
53 | Now, with this method in place we could change ("refactor") our previous methods
54 | to use it:
55 |
56 | ```ruby
57 | def sum(number, other)
58 | number + other
59 | end
60 |
61 | def add_one(number)
62 | sum(number, 1)
63 | end
64 |
65 | def add_two(number)
66 | sum(number, 2)
67 | end
68 |
69 | puts add_one(3)
70 | puts add_two(3)
71 | ```
72 |
73 | Again, these examples are not super realistic, as we'd probably just use the
74 | `+` operator in the first place, in practice.
75 |
76 | However, we think this nicely demostrates how you can use one method from
77 | another ... and how different methods require different numbers of arguments.
78 |
79 | We'll look at a more realistic example in the next chapter.
80 |
--------------------------------------------------------------------------------
/source/10-writing_methods/07-printing.md:
--------------------------------------------------------------------------------
1 | # Printing things
2 |
3 | Many of the exercises that you do while doing your first steps with Ruby
4 | basics include running a short Ruby program that outputs something to the
5 | terminal.
6 |
7 | So far, we have mostly used the method `puts` to do that.
8 |
9 | However, there's another method that is even more useful when we are trying
10 | to figure out what a program is doing, why it is doing it, and what a certain
11 | error might be about.
12 |
13 | This method is the method `p`. In order to understand `p` better, we want to
14 | look at another method first, which is the method `inspect`.
15 |
16 | The method `inspect` is available on any object in Ruby. It returns a string
17 | that is a representation of the object itself: a representation that is as
18 | close as possible to the code that you use to create the object. So `inspect`
19 | is useful to inspect objects, duh :)
20 |
21 | This becomes more clear when you try it in IRB:
22 |
23 | ```ruby
24 | $ irb
25 | > puts 5.inspect
26 | 5
27 |
28 | > puts "A string".inspect
29 | "A string"
30 |
31 | > puts [1, 2, 3].inspect
32 | [1, 2, 3]
33 | ```
34 |
35 | As you can see the string returned from `inspect` is exactly the same as the
36 | Ruby code that we used to create the object. That is really convenient.
37 |
38 | However, typing `puts something.inspect` is quite a bit of work to do. That's
39 | 12 characters to type next to the object itself!
40 |
41 | Therefore Ruby has a method to make our lifes easier, and does this work for us.
42 | That's the method `p`.
43 |
44 | This method is implemented like so:
45 |
46 | ```ruby
47 | def p(object)
48 | puts object.inspect
49 | end
50 | ```
51 |
52 | Whenever you are trying to figure out what a certain line of code does, what's
53 | assigned to a variable, or what a method call returns, we recommend to use `p`
54 | because it tells you exactly what the thing that you are looking at is.
55 |
56 | `puts` on the other hand tries to be smart.
57 |
58 | For example when you pass an array to `puts` then it will output each of the
59 | objects on a separate line:
60 |
61 | ```ruby
62 | $ irb
63 | > something = [1, 2, 3]
64 | > puts something
65 | 1
66 | 2
67 | 3
68 | ```
69 |
70 | Also, the output for numbers and strings that contain numbers is exactly the
71 | same when you use `puts`:
72 |
73 | ```ruby
74 | $ irb
75 | > puts 123
76 | 123
77 | > puts "123"
78 | 123
79 | ```
80 |
81 | From the output of `puts` it often is not clear whether the object that you are
82 | looking it is an array that contains numbers, or an array that contains
83 | strings, or just a long string that contains linebreaks.
84 |
85 | In short, `puts` is useful when you are writing a program that is supposed to
86 | actually output something to the screen. Like, this could be a command line
87 | tool that you write in order to make your own life easier at your job, and that
88 | is helpful at automating some repetitive work. Or it is useful in Ruby
89 | programming exercises :)
90 |
91 | On the other hand `p` is useful when you are trying to understand what your
92 | code does, e.g. when you are trying to figure out a certain error.
93 |
94 |
--------------------------------------------------------------------------------
/source/11-writing_classes.md:
--------------------------------------------------------------------------------
1 | # Writing classes
2 |
3 | *Finally, our first own class*
4 |
5 | Since in Ruby "everything is an object", we have worked with objects quite a
6 | bit already.
7 |
8 | We've created numbers, Strings, and seen objects like `true`, `false`, and
9 | `nil`. We have also looked at their class names by calling, e.g. `"a
10 | string".class`, and we have explored some other methods that these objects
11 | have. We have also talked about how you can define your own methods, and how
12 | you can call them, passing arguments as required.
13 |
14 | That means we now have all the tools that we need to finally learn how to
15 | define and use your own classes. And this is where things suddenly become even
16 | more fun!
17 |
18 | You can think of objects as having two things: They know *stuff*, and they can
19 | *do something* with stuff (their own stuff, as well as the stuff that gets
20 | passed to them).
21 |
22 | Imagine you were an object that is an instance of the class `Person`. Well, in
23 | a certain way, you actually are :)
24 |
25 | Since you are a `Person`, you are able to remember your own name. And you are
26 | able to do something with it: When asked, you can tell your name to others,
27 | that is, you can return it to the "caller", to whoever asked.
28 |
29 | We'll define this exact class in just a few chapters. However, before we do
30 | that, we'll first look at how to define the method `add_two` to a class
31 | `Calculator` ... just because we can, and because you're already familiar with
32 | these methods.
33 |
34 |
--------------------------------------------------------------------------------
/source/11-writing_classes/01-definition.md:
--------------------------------------------------------------------------------
1 | # Defining classes
2 |
3 | Let's start by creating a class `Calculator`, and adding some methods to it,
4 | step by step.
5 |
6 | In Ruby, you define a class like this:
7 |
8 | ```ruby
9 | class Calculator
10 | end
11 | ```
12 |
13 | That's all. It's not a very useful class, since it's completely empty, but
14 | it's a class.
15 |
16 |
17 | A class is defined using the keyword class, a name, and the
18 | keyword end.
19 |
20 |
21 | Also, you see that the class has the name `Calculator`, which starts with an
22 | uppercase letter. In Ruby, this is required, and you'd get an error if you
23 | tried to define a class `calculator`.
24 |
25 | Also, for class names that consist of several words the Ruby community has the
26 | convention to separate these words by uppercase letters, as in
27 | `RubyStudyGroup`. This is called CamelCase, because of the humps. Whereas for
28 | variable and method names we use underscores, and keep everything lowercase:
29 | `local_variable` and `method_name`. This is called snake_case.
30 |
31 |
32 | Class names must start with an uppercase letter, and should use CamelCase.
33 | Variable and methods names should use snake_case.
34 |
35 |
36 | Ok, back to our class `Calculator`.
37 |
38 | Since we've defined a full, valid class, we can now already use it to create a
39 | new, concrete calculator instance, an object from it.
40 |
41 | You can think about the instance as the concrete calculator object that you can
42 | hold in your hands, and use to do actual calculations. The class on the other
43 | hand is more like the idea or concept of a calculator, like the idea of it that
44 | you have when you order a calculator online.
45 |
46 | Ok, here's how to do create a new, concrete instance from our class:
47 |
48 | ```ruby
49 | Calculator.new
50 | ```
51 |
52 | That's right. `new` is a method, and it is defined on the class itself (which,
53 | as you might remember, is also an object, so it can have methods). This method
54 | creates a new instance of the class, and returns it.
55 |
56 |
57 | The method new is defined on every class, and returns a new
58 | instance of the class.
59 |
60 |
61 | Cool. Let's have a look at that object:
62 |
63 | ```ruby
64 | p Calculator.new
65 | ```
66 |
67 | The output will seem a little bit weird, and technical at first:
68 |
69 | ```
70 | #
71 | ```
72 |
73 | The format `#<...>` tells you that this object is not a simple thing like a
74 | number, string, or array. Instead, it just tells you the name of the class,
75 | `Calculator`, and the internal id that Ruby has assigned to this object.
76 |
77 | Every object has its own, unique, internal object id, and when I ran this code
78 | on my computer, Ruby assigned the id `0x007fb2fbe50910`. If you run it,
79 | you'll get a different one. In practice, most of the time, you can simply ignore
80 | this id.
81 |
82 | Also, we can check that our new calculator instance indeed is an instance of
83 | the class `Calculator`:
84 |
85 | ```ruby
86 | $ irb
87 | > class Calculator
88 | > end
89 | > calculator = Calculator.new
90 | > calculator.class
91 | => Calculator
92 | > calculator.is_a?(Calculator)
93 | => true
94 | ```
95 |
--------------------------------------------------------------------------------
/source/11-writing_classes/03-initializers.md:
--------------------------------------------------------------------------------
1 | # Initializing objects
2 |
3 | *In the moment of birth*
4 |
5 | Let's start over, and define a new class.
6 |
7 | Remember how we said that objects can be thought of as two things: They know
8 | *stuff*, and they can *do things*.
9 |
10 | Let's define a class `Person`. People obviously also know things, and can do things.
11 |
12 | Here's how to define a shiny, new, empty class `Person`:
13 |
14 | ```ruby
15 | class Person
16 | end
17 | ```
18 |
19 | Again, that's not a very useful class, but we can instantiate it, and create an
20 | actual, concrete person instance (object) from it:
21 |
22 | ```ruby
23 | p Person.new
24 | ```
25 |
26 | Now, before we add any behaviour (methods) to our class, we want to be able to
27 | give it some initial data: In our case, we want the person to know its own
28 | name.
29 |
30 | We can do this like so:
31 |
32 | ```ruby
33 | class Person
34 | def initialize(name)
35 | end
36 | end
37 | ```
38 |
39 | You see that we add a method called `initialize` to the class, and this method
40 | accepts a single argument, which is called `name`. At the moment, this method
41 | is still empty. We'll add some code to it in a bit.
42 |
43 | The important bit to learn for you is: the method `initialize` is a special
44 | method with a special meaning in Ruby:
45 |
46 | Whenever you call the method `new` on a class, as in `Person.new`, the class
47 | will create a new instance of itself. It will then, internally, call the method
48 | `initialize` on the new object. Doing so it will simply *pass all the
49 | arguments* that you passed to `new` *on to* the method `initialize`.
50 |
51 | So we can now create a new person instance by calling ...
52 |
53 | ```ruby
54 | Person.new("Ada")
55 | ```
56 |
57 | ... and the string `"Ada"` will be passed on to our `initialize` method, and
58 | end up being assigned to the local variable `name`.
59 |
60 |
61 | The special method initialize is called under the hood when the
62 | object has been created by the class method new.
63 |
64 |
65 | Obviously, our `initialize` method does not *do* anything with the String
66 | passed, yet. That's right. We'll get to that in the next chapter.
67 |
68 | To recap, when you call `new` on the class `Person`, and pass the string
69 | `"Ada"` then the method `new` will create a new instance of the class, and call
70 | `initialize` on it, passing the same argument list, which in our case is the
71 | single string `"Ada"`.
72 |
73 | When we create a new instance of a class by the way of calling the method `new`
74 | on that class, we also say that we "instantiate" that object: By calling
75 | `Person.new` we instantiate a new person object.
76 |
77 |
78 |
--------------------------------------------------------------------------------
/source/11-writing_classes/04-instance_variables.md:
--------------------------------------------------------------------------------
1 | # Instance variables
2 |
3 | *An object's own knowledge*
4 |
5 | Now that you understand how the string that we pass to the method `new`
6 | ends up being passed to the new object's `initialize` method, we can start
7 | improving `initialize`, so it does something with the string, and actually
8 | *initializes* our new object:
9 |
10 | ```ruby
11 | class Person
12 | def initialize(name)
13 | @name = name
14 | end
15 | end
16 | ```
17 |
18 | This introduces another new concept: `@name` is a new type of variable, called
19 | an "instance variable".
20 |
21 | The body of the `initialize` method now does nothing else but assign the value
22 | of the local variable `name` to an instance variable `@name`.
23 |
24 | You remember how we said that each method has its own local scope, which is
25 | created when the method is called, and populated with local variables from the
26 | arguments list. You have also learned that this scope is erased, and thrown
27 | away when Ruby exits the method body and returns from the method. And that
28 | local variables that are visible in one method are not visible in other
29 | methods: that's why they are called local.
30 |
31 | Now, the thing is: Every *object* also has its own scope.
32 |
33 | An object's scope is populated with instance variables, in the moment we assign
34 | something to them. And they are visible *everywhere* in the object, that is, in
35 | every method that the object has.
36 |
37 |
38 | Instance variables live in, and are visible everywhere in the object's scope.
39 |
40 |
41 | You can think of the object's scope as your own knowledge, or memories.
42 |
43 | For example, you know your name, your email address, and your email password.
44 | You keep this knowledge around, and you can use it when you do things (such as
45 | responding to another person). Likewise, an object keeps its instance variables
46 | around, as long as the object exists.
47 |
48 | Ok, let's see how that works in practise.
49 |
50 | If you create, and output an instance of our class `Person`, you'll see that
51 | Ruby now prints out the instance variable, too:
52 |
53 | ```ruby
54 | person = Person.new("Ada")
55 | p person
56 | ```
57 |
58 | The first line creates a new instance of the class `Person`, passing the string
59 | `"Ada"`, and assign this new object to the variable `person`. The second line
60 | will then print it out:
61 |
62 | ```
63 | #
64 | ```
65 |
66 | As you can see this includes the instance variable `@name` with the value
67 | `"Ada"`: This specific, concrete instance of the class `Person` knows their
68 | name.
69 |
70 | You can think of this as you, as a programmer, creating this new person, and
71 | in the moment of its creation, its birth, you also give it a name. Which kind
72 | of how it works with real people, too, isn't it?
73 |
74 | Hmm, well ... Yeah, sort of. Anyhow, let's move on.
75 |
--------------------------------------------------------------------------------
/source/11-writing_classes/06-attribute_writers.md:
--------------------------------------------------------------------------------
1 | # Attribute writers
2 |
3 | *Setting information*
4 |
5 | Imagine in our application a person not only needs a name, but also a password.
6 | However, let's also imagine that, at the time of the creation of a new person
7 | instance, this password is not yet known. (Who would give a toddler an email
8 | password anyway?)
9 |
10 | Instead we want to be able to tell the person object about its email password
11 | later.
12 |
13 | We can do this like so:
14 |
15 | ```ruby
16 | class Person
17 | def initialize(name)
18 | @name = name
19 | end
20 |
21 | def name
22 | @name
23 | end
24 |
25 | def password=(password)
26 | @password = password
27 | end
28 | end
29 | ```
30 |
31 | As you can see, the method `password=` does nothing else but take a single
32 | argument (called `password`) and assign the value of this local variable to the
33 | instance variable `@password`.
34 |
35 | This method's structure looks exactly the same as the method `initialize`,
36 | doesn't it? Execpt that `initialize` is called whenever you call `new` on the
37 | class. Our new method `password=` needs to be called on the object itself,
38 | once it has been created.
39 |
40 | Again, because this kind of method is used so often, there's another name for
41 | it: it's an attribute writer. (And again, we think it should have been called
42 | an "instance variable writer" instead.)
43 |
44 | Now, we can use the attribute writer like so:
45 |
46 | ```ruby
47 | person = Person.new("Ada")
48 | person.password=("super secret")
49 | p person
50 | ```
51 |
52 | If you execute this, then it will print out:
53 |
54 | ```
55 | #
56 | ```
57 |
58 | So, yeah, we can see that, after calling `person.password=("super secret")`
59 | the object now has an instance variable defined, i.e., the person now knows
60 | their password, too.
61 |
62 |
63 | An attribute writer allows setting an instance variable.
64 |
65 |
66 | That method call looks a little odd though, doesn't it?
67 |
68 | Remember what we've said above about the syntax sugar that Ruby adds for the
69 | assignment operator `=`?
70 |
71 | Exactly the same works for attribute writers, that is, methods that end with an
72 | equals sign `=`.
73 |
74 | That's right. So we can also write this instead:
75 |
76 | ```ruby
77 | person = Person.new("Ada")
78 | person.password = "super secret"
79 | ```
80 |
81 | And this reads just so much better, doesn't it?
82 |
83 | Just remember that, under the hood, when running your code, Ruby translates the
84 | line `person.password = "something"` to `person.password=("something")`, and
85 | this simply calls the method `password=`, passing the value on the right hand
86 | side as an argument: it's just another method :)
87 |
88 | We think this is pretty cool.
89 |
--------------------------------------------------------------------------------
/source/11-writing_classes/07-state_and_behaviour.md:
--------------------------------------------------------------------------------
1 | # State and behaviour
2 |
3 | *Data and methods*
4 |
5 | Lets have another look our class definition for `Person`:
6 |
7 | ```ruby
8 | class Person
9 | def initialize(name)
10 | @name = name
11 | end
12 |
13 | def name
14 | @name
15 | end
16 |
17 | def password=(password)
18 | @password = password
19 | end
20 | end
21 | ```
22 |
23 | Do you notice something?
24 |
25 | Our class demonstrates an important thing about objects:
26 |
27 | There's a way to ask a person for their `name`, but no way to set a new name.
28 | On the other hand there's a way to set a new password to the person, but no way
29 | to ask for it.
30 |
31 | If you think about it, that makes sense, doesn't it?
32 |
33 | If you join our Ruby beginners study group for the first time, and we ask you for
34 | your name, you'll happily tell it. But if we ask for your Gmail password, you
35 | will probably just laugh at us, or stare at us, or show some other error
36 | message. ;) In any case, you won't tell us your email password, because that's
37 | private information.
38 |
39 | The same is also true for objects.
40 |
41 | Every object has its own object scope that might hold a bunch of instance
42 | variables. These are private to the object. Our person object knows their
43 | password, once it has been given to them. But from then on, they won't tell
44 | anyone the password, because there's no method for that. On the other hand,
45 | there's a method `name`, which is an attribute reader, so we can ask our person
46 | object for their name. But there's no way for others to give a new name to the
47 | person, because there's no method for that, no attribute writer `name=`.
48 |
49 | This concept is called *encapsulation*, and it is one of the main motivations
50 | behind the whole paradigm of object-oriented programing:
51 |
52 | We can say that an object encapsulates state (data, knowledge), which is
53 | private to the object, and exposes behaviour by the way of having publicly
54 | accessible methods.
55 |
56 |
57 | Objects have state (instance variables) and behaviour (methods).
58 |
59 |
60 | So, we have now created our first little class, and it's one that you could
61 | actually see in real applications.
62 |
63 |
--------------------------------------------------------------------------------
/source/13-blocks.md:
--------------------------------------------------------------------------------
1 | # Blocks
2 |
3 | *Like methods, but without a name*
4 |
5 | Blocks are one of the things programmers absolutely love about Ruby. They are
6 | an extremely powerful feature that allows us to write very flexible code. At
7 | the same time they read very well, and they are used all over the place.
8 |
9 | So, what is a block?
10 |
11 | A block, essentially, is the same thing as a method, except it does not have a
12 | name, and does not belong to an object.
13 |
14 | I.e. a block is an anonymous piece of code, it can accept input in form of
15 | arguments (if it needs any), and it will return a value, but it does not have a
16 | name.
17 |
18 | Moreover, blocks can only be created by the way of passing them to a method
19 | when the method is called.
20 |
21 |
22 | A block is a piece of code that accepts arguments, and returns a value. A block
23 | is always passed to a method call.
24 |
25 |
26 | Let's jump right in:
27 |
28 | ```ruby
29 | 5.times do
30 | puts "Oh, hello from inside a block!"
31 | end
32 | ```
33 |
34 | As you can see `times` is a method that is defined on numbers: `5.times` calls
35 | the method `times` on the number `5`.
36 |
37 | Now, when this method is called the only thing passed is a block: that is the
38 | anonymous piece of code between `do` and `end`. There are no objects passed as
39 | arguments to the method `times`, instead it just passes a block.
40 |
41 | The method `times` is implemented in such a way that it simply calls (executes)
42 | the block 5 times, and thus, when you run the code, it will print out the
43 | message `"Oh, hello from inside a block!"` 5 times.
44 |
45 | The code almost reads like an English sentence *Five times do output this
46 | message*, right? It does, and that's one of the reasons why Rubyists love
47 | using blocks.
48 |
49 | One of the things that seem rather hard to grasp about blocks is that
50 |
51 | * First, they are anonymous chunks of code.
52 | * Second, they are passed to methods just like other objects.
53 | * And third, they still can be called (just like methods), from inside the
54 | method that it was passed to.
55 |
56 | Does that make sense?
57 |
58 | Imagine you are the object that represents the number `5`. You are a number and
59 | you do know your own value.
60 |
61 | Now I hand you a piece of paper saying: `Please print the following on the
62 | screen: "Oh, hello!"`, and I ask you to execute this instruction as many times
63 | as the value that you know.
64 |
65 | You'd go ahead and follow the instructions on the paper, and thus print out the
66 | message. You repeat this 5 times, because `5` is the value that you know.
67 |
68 | This is pretty much how the method `times` on numbers works, and how blocks
69 | work: `times` takes the block (the instructions), and runs it as many times
70 | as the value of the number.
71 |
72 | To summarize: Methods can not only accept input in the form of objects passed
73 | as arguments. They can also accept this one special piece of input, which is
74 | an anonymous block of code. And they can then call (execute) this block of code
75 | in order to do useful things with it.
76 |
77 | Let's look at some other aspects of how blocks work next.
78 |
--------------------------------------------------------------------------------
/source/13-blocks/01-syntax.md:
--------------------------------------------------------------------------------
1 | # Alternative block syntaxes
2 |
3 | Next to the syntax shown before, using `do` and `end`, Ruby comes with an
4 | alternative syntax, which uses curly braces for defining a block.
5 |
6 | These two statements do exactly the same:
7 |
8 | ```ruby
9 | 5.times do
10 | puts "Oh, hello!"
11 | end
12 |
13 | 5.times { puts "hello!" }
14 | ```
15 |
16 | Both statements define a block, which is passed to the method `times`. And
17 | both blocks contain a single line of code.
18 |
19 |
20 | Blocks can be defined enclosing code in do and end,
21 | or curly braces {}.
22 |
23 |
24 | So, when do you use one or the other syntax?
25 |
26 | In the Ruby community there's the convention to use curly braces if you have a
27 | single line block and it fits nicely on the same line (as, in our example, it
28 | does).
29 |
30 | Whenever you need to have more than one line in your block, then you use the
31 | syntax using `do` and `end`. Sometimes people also use the `do` and `end`
32 | syntax when they feel it makes the code more readable.
33 |
34 |
35 | Use curly braces {} for blocks, when the code fits on one line.
36 |
37 |
38 |
--------------------------------------------------------------------------------
/source/13-blocks/02-arguments.md:
--------------------------------------------------------------------------------
1 | # Block arguments
2 |
3 | Blocks make a lot of sense on methods that are defined on collections like
4 | arrays and hashes.
5 |
6 | Let's have a look at some examples with arrays.
7 |
8 | In our previous example that used the method `times` our block did not accept
9 | an argument. A block that accepts an argument looks like this:
10 |
11 | ```ruby
12 | [1, 2, 3, 4, 5].each do |number|
13 | puts "#{number} was passed to the block"
14 | end
15 | ```
16 |
17 | And, again, this is the same as:
18 |
19 | ```ruby
20 | [1, 2, 3, 4, 5].each { |number| puts "#{number} was passed to the block" }
21 | ```
22 |
23 | It is unknown to us why Matz has chosen to not enclose the argument list of
24 | a block with round parentheses just like method argument lists. Instead, Ruby
25 | wants us to use vertical bars (we call them "pipes").
26 |
27 | So, for blocks, `do |number|` is the same that is `def add_two (number)` for a
28 | method definition, except that the method wants a name while a block is
29 | anonymous: `|number|` and `(number)` both are argument lists. The first one
30 | is used for blocks, the second one for methods.
31 |
32 |
33 | Block arguments are listed between pipes |, instead of parentheses.
34 |
35 |
36 | Now, when you run the code example above, you'll see the message printed out
37 | for each of the numbers contained in the array.
38 |
39 | Does that make sense? Again, our code almost reads like an English sentence:
40 |
41 | *With this array for each of its elements, naming it `number`, output the
42 | following message.*
43 |
44 | The method `each` is defined on arrays, and it does just this:
45 |
46 | It takes each of the elements in the array and calls the block, passing the
47 | element as an argument. The block can then do whatever you want it to do with
48 | the element. In our case we interpolate it into a string and print it out to
49 | the screen.
50 |
--------------------------------------------------------------------------------
/source/13-blocks/04-ioc.md:
--------------------------------------------------------------------------------
1 | # Inversion of control
2 |
3 | In Ruby there are a lot more methods that accept blocks, and they do very
4 | different things. However, they have one thing in common:
5 |
6 | By accepting a block, from you as a programmer, the method can pass control to
7 | you.
8 |
9 | This design is an example for the principle of *inversion of control*, and
10 | it's the real reason why Rubyists love blocks so much.
11 |
12 | What does that mean?
13 |
14 | In short it means that Matz, the creator of Ruby, put a tool in place that can
15 | be used to allow methods to pass control to its users (i.e. you as a
16 | programmer).
17 |
18 | "Control" in this context refers to the question who gets to decide how things
19 | work.
20 |
21 | In older languages, where there was no such tool, people either had to
22 | implement lots of very specific methods, and *guess* what users might need in
23 | the future. Or they'd decide to just not implement any of these methods at all.
24 |
25 | For example, in Ruby, we don't have to define lots of methods like `select_odd`,
26 | `select_even`, `select_lesser_than`, `select_greater_than` and so on, ... where
27 | each of these methods would be useful for one very specific usecase.
28 |
29 | Instead, the class `Array` only has to implement one single, very generic
30 | method for arrays: `select`. Since Ruby has blocks, the method can allow you
31 | (as a programmer) to specify the criterion yourself: by passing a piece of
32 | code, in the form of block to the method.
33 |
34 | That way Ruby lets you, as a programmer, take over control, and specify what is
35 | used as a criterion to select elements.
36 |
37 | One of the reasons we mention this is because we think this is a nice example
38 | of a pretty abstract principle applied to software design. There are lots of
39 | other principles like these, and they'll make more and more sense to you over
40 | time. Programming languages and code, from this perspective, is a subject of
41 | design, and thus art, as well as social and cultural questions ... much rather
42 | than strictly logical or technical ones.
43 |
--------------------------------------------------------------------------------
/source/13-blocks/05-iterators.md:
--------------------------------------------------------------------------------
1 | # Iterators
2 |
3 | Methods on arrays and hashes that take a block are also called iterators.
4 |
5 | We say they *iterate over the array*, meaning that these methods take each
6 | element of the array and do something with it.
7 |
8 | In Ruby iterators are "chainable", adding functionality on top of each other.
9 |
10 | That means that, if you do not pass a block to an iterator method, such as
11 | `each`, `collect`, `select`, then you'll get an *iterator object* back. You can
12 | then call more methods on these iterator objects, and finally pass a block.
13 | Like so:
14 |
15 | ```ruby
16 | numbers = [1, 2, 3, 4, 5].collect.with_index do |number, index|
17 | number + index
18 | end
19 | p numbers
20 | ```
21 |
22 | This will print out:
23 |
24 | ```
25 | [1, 3, 5, 7, 9]
26 | ```
27 |
28 | What's going on here?
29 |
30 | The method `with_index` can be called on any iterator object. All it does is
31 | pass the index of the element within the array to the block, as a second block
32 | argument, in addition to the element itself.
33 |
34 | Inside of the block we can then use it, and add the index to the number itself.
35 |
36 | So for the first iteration it will call the block with `1` and `0`, since `0` is
37 | the first "position", that is, index. It therefore returns `1`. For the second
38 | iteration it calls the block with `2` and `1`, and returns `3`, and so on.
39 |
40 | Therefore the method call eventually returns the array `[1, 3, 5, 7, 9]`.
41 |
42 |
43 | Iterators in Ruby are chainable.
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/source/13-blocks/10-methods_using_blocks.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/13-blocks/10-methods_using_blocks.md
--------------------------------------------------------------------------------
/source/14-conditionals.md:
--------------------------------------------------------------------------------
1 | # Conditionals
2 |
3 | *If this is true, then do that. Otherwise do something else.*
4 |
5 | Often we want to check for a certain condition, and then based on it, do
6 | either one thing or another. Or we want to do something only if a condition is
7 | true.
8 |
9 | All practical programming languages have some way of expressing this, and in
10 | Ruby it looks like so:
11 |
12 | ```ruby
13 | number = 5
14 |
15 | if number.between?(1, 10)
16 | puts "The number is between 1 and 10"
17 | elsif number.between?(11, 20)
18 | puts "The number is between 11 and 20"
19 | else
20 | puts "The number is bigger than 20"
21 | end
22 | ```
23 |
24 | You can probably guess what it does, and how it works, can't you?
25 |
26 | Let's walk through it one by one:
27 |
28 | * If you run this code it will print out `The number is between 1 and 10`,
29 | because the number assigned to the variable `number` on the first line is
30 | `5`, and for this number the method call `number.between?(1, 10)` returns
31 | `true`. Ruby will therefore execute the code in the `if` branch: The `if`
32 | branch is the block of code that comes after the line with the `if`
33 | statement, and that is indented by two spaces. Once it is done executing
34 | the `if` branch Ruby will simply ignore the rest of the statement.
35 |
36 | * If you change the number `5` on the first line to `15`, and run the code
37 | again, then it will print out `The number is between 11 and 20`. In this
38 | case Ruby will, again, first check the first condition `number.between?(1,
39 | 10)`, but this time this method call returns `false`. Therefore, Ruby will
40 | ignore the `if` branch, and check the next condition on the `elsif` line:
41 | `number.between?(11, 20)`. Now, this method call returns true, because `5` is
42 | between `11` and `20`. Ruby will therefore execute the `elsif` branch, and
43 | print out this message. Again, once it is done executing the `elsif` branch
44 | Ruby will ignore the rest of the statement.
45 |
46 | * If you now change the number `15` to `25`, and run the code again, then it
47 | will print out `The number is bigger than 20`. Again, Ruby will first check
48 | the first condition, and find it returns `false`. It will check the second
49 | condition, which now also returns `false`. Therefore Ruby will then execute
50 | the `else` branch, and print out that message.
51 |
52 | The `elsif` and `else` statements and branches are optional: you don't need to
53 | have them. You can have an `if` statement without `elsif` or `else` branches,
54 | an `if` statement only with an `else`, or you could have an `if` statement with
55 | one or more `elsif` statements. Or combine all of them together:
56 |
57 | * There *must* be an `if` statement and branch.
58 | * There *can* be many `elsif` statements and branches.
59 | * There *can* be one `else` statement and branch.
60 |
61 |
--------------------------------------------------------------------------------
/source/14-conditionals/01-shorthand.md:
--------------------------------------------------------------------------------
1 | # Shorthand syntax
2 |
3 | ## Trailing If
4 |
5 | One particularly nice feature in Ruby is that we can append the `if` statement
6 | to the code on the `if` branch if it's just a single line. So instead of this:
7 |
8 | ```ruby
9 | if number.odd?
10 | puts "The number is odd."
11 | end
12 | ```
13 |
14 | we can also write this:
15 |
16 | ```ruby
17 | puts "The number is odd." if number.odd?
18 | ```
19 |
20 | which not only saves us two lines, it also reads great!
21 |
22 | ## Unless
23 |
24 | Also, as well as `if` Ruby also knows a statement `unless` for when we want to do
25 | something if the condition does *not* apply (evaluate to true). And again, we
26 | can also append the `unless` statement to the end of the line, so these two are
27 | the same:
28 |
29 | ```ruby
30 | unless number.odd?
31 | puts "The number is not odd."
32 | end
33 |
34 | puts "The number is not odd." unless number.odd?
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/source/14-conditionals/02-return_values.md:
--------------------------------------------------------------------------------
1 | ## Conditionals return values
2 |
3 | Another extremely useful aspect about `if` and `unless` statements in Ruby is
4 | that they return values.
5 |
6 | Yes, that's right:
7 |
8 | An `if` statement, with all of its branches, as a whole, evaluates to the value
9 | returned by the statement that was last evaluated, just like a method does.
10 |
11 | For example, instead of this:
12 |
13 | ```ruby
14 | if number.even?
15 | puts "The number is even"
16 | else
17 | puts "The number is odd"
18 | end
19 | ```
20 |
21 | we can also assign the return value of the `if` statement to a variable, and
22 | then output it:
23 |
24 | ```ruby
25 | message = if number.even?
26 | "The number is even"
27 | else
28 | "The number is odd"
29 | end
30 |
31 | puts message
32 | ```
33 |
34 | Also, for the same reason, if we define a method that contains nothing but a
35 | single `if`/`else` statement, the method will, again, return the last statement
36 | evaluated:
37 |
38 | ```ruby
39 | def message(number)
40 | if number.even?
41 | "The number is even"
42 | else
43 | "The number is odd"
44 | end
45 | end
46 |
47 | puts message(2)
48 | puts message(3)
49 | ```
50 |
51 | The first method call `message(2)` will output `The number is even`, and the
52 | second one `message(3)` will output `The number is odd`.
53 |
--------------------------------------------------------------------------------
/source/15-operators.md:
--------------------------------------------------------------------------------
1 | # Operators
2 |
3 | We've already used some arithmetic operators (`+` and `*`) above. You have
4 | also learned that operators, under the hood, are just methods. Ruby just
5 | adds a little bit of syntax sugar on top of these methods, so they're sweeter
6 | to read, and write.
7 |
8 | There also are operators for comparing things, for logical calculations, and
9 | other operations. Let talk about some more of them.
10 |
11 |
--------------------------------------------------------------------------------
/source/15-operators/01-arithmetical.md:
--------------------------------------------------------------------------------
1 | # Arithmetical operators
2 |
3 | For numbers, the operators `+` and `*` obviously mean the mathematical
4 | operations of adding and multiplying two numbers. Of course there are other
5 | arithmetical operators. Here's a full list:
6 |
7 | * `+` - addition
8 | * `-` - subtraction
9 | * `*` - multiplication
10 | * `/` - division
11 | * `**` - exponentiation
12 | * `%` - modulus (the rest of a division, e.g. `5 % 2` returns `1`)
13 |
14 | However, some of these methods are also defined on other objects, like strings
15 | and arrays.
16 |
17 | Try it yourself in IRB:
18 |
19 | ```ruby
20 | $ irb
21 | > "<3" + "!"
22 | => "<3!"
23 |
24 | > "<3" * 3
25 | => "<3<3<3"
26 | ```
27 |
28 | As you can see, these operators mean something different for strings. But they
29 | also make sense, don't they?
30 |
31 | Adding one string to another just means that they will be concatenated into one
32 | longer string. And multiplying a string by a number means repeating it as many
33 | times.
34 |
35 | The same works for arrays:
36 |
37 | ```ruby
38 | $ irb
39 | > [1, 2] + [3, 4]
40 | => [1, 2, 3, 4]
41 |
42 | > [1, 2] * 3
43 | => [1, 2, 1, 2, 1, 2]
44 | ```
45 |
46 | Again, adding two arrays means combining them into one big array. And
47 | multiplying an array with a number means getting a big array with the original
48 | elements repeated.
49 |
--------------------------------------------------------------------------------
/source/15-operators/02-logical.md:
--------------------------------------------------------------------------------
1 | # Logical operators
2 |
3 | Logical operators are also, maybe more commonly, called boolean operators.
4 |
5 | The term "boolean" originates from the book "The Mathemetical Analysis of
6 | Logic" written by George Boole in 1847. Boolean logic has been fundamental in
7 | the development of computers, and programming, since at their core, computers
8 | are all about processing whether or not there is current flow: on vs off
9 | (true vs false).
10 |
11 | If you are curious, feel encouraged to google and read up on this online, but
12 | for now, we can simply look at the 3 fundamental boolean operators and
13 | what they do: `and`, `or`, and `not`.
14 |
15 | The operator `and` returns `true` if, and only if, both values also are `true`.
16 | So, only the expression `true and true` is also `true`. All of the expressions
17 | `true and false`, `false and true`, `false and false` evaluate to `false`.
18 |
19 | If you think about this, and come up with English sentences, then this will
20 | make a lot of sense: *At the restaurant I'll have a tomato soup IF it is vegan
21 | AND they still have some.*
22 |
23 | The operator `or` on the other hand returns `true` if at least one of the
24 | values is `true`. So, only if both values are `false`, the operator returns
25 | `false`.
26 |
27 | That's why it is logically correct to answer the question *Would you like tea
28 | or coffee for breakfeast?* with *Yes, please.* IF you'd like either tea, or
29 | coffee, or both. You'd only say *Hell, no!* if you'd like an orange juice
30 | instead :)
31 |
32 | The operator `not` simply returns the negated, opposite value. `not true`
33 | returns `false`, and `not false` returns `true`. Therefore, the following
34 | lines of code are the same:
35 |
36 | ```ruby
37 | puts "Always true" if not false
38 | puts "Always true" unless false
39 | ```
40 |
41 | Each of these three operators comes in two versions:
42 |
43 | * `and` and `&&`
44 | * `or` and `||`
45 | * `not` and `!`
46 |
47 | The difference between them has to do with what is called "operator precedence".
48 |
49 | From math you know that `1 + 2 * 3` evaluates to `7`, not `9`. This is
50 | because the multiplication `*` operator binds stronger, and precedes the
51 | addition operator `+`. In other words `1 + 2 * 3` is same as `1 + (2 * 3)`, and
52 | not the same as `(1 + 2) * 3`.
53 |
54 | In Ruby, the operators `&&`, `||`, and `!` bind stronger than, and thus precede
55 | their fellows `and`, `or`, and `not`.
56 |
--------------------------------------------------------------------------------
/source/15-operators/03-comparison.md:
--------------------------------------------------------------------------------
1 | # Comparison operators
2 |
3 | In order to compare things Ruby has a bunch of comparison operators.
4 |
5 | The operator `==` returns true if both objects can be considered the same. For
6 | example `1 == 1 * 1` will return `true`, because the numbers on both sides
7 | represent the same value. The expression `"A" == "A"` also returns `true`
8 | because both strings have the same value.
9 |
10 | Likewise, two arrays are equivalent when they contain the same elements, in the
11 | same order. For example `[1, 2] == [1, 2]` will return `true`, but `[1, 2] ==
12 | [2, 3]` and `[1, 2] == [2, 1]` both will return `false`.
13 |
14 | Note that we say "considered the same" and "equivalent" because technically the
15 | two objects do not have to be (and most often, as in our examples) are not the
16 | same objects. E.g. while evaluating the expression `"A" == "A"` Ruby will
17 | actually create two different string objects which both contain a single
18 | character `A`.
19 |
20 | In practice this is almost always what you want. For the rare case when you
21 | actually need to check if two objects are the same object there's the method
22 | `equal?`. E.g., `"A".equal?("A")` returns `false`.
23 |
24 | Other comparison operators are: less than `<` , less than or equal `<=`, greater than `>`,
25 | and greater than or equal `>=`. They also work on numbers and strings, in the way
26 | you'll expect it. Open IRB and try a few combinations on numbers and strings.
27 |
28 | Comparison operators most often are used in order to formulate conditions
29 | in `if` statements. Like so:
30 |
31 | ```ruby
32 | number = 20
33 | puts "#{number} is greater than 10." if number > 10
34 | ```
35 |
36 | The most funny operator in Ruby is `<=>`, because it's called the spaceship
37 | operator. No kidding :) It is rather rarely used, and it is useful for
38 | implementing custom ways of sorting things.
39 |
--------------------------------------------------------------------------------
/source/15-operators/04-methods.md:
--------------------------------------------------------------------------------
1 | # Operators are methods
2 |
3 | As you have seen a number has methods named like the arithmetic operators `+`,
4 | `-`, `*`, and `/`. That's right! Interesting.
5 |
6 | If you think about this, it makes sense: If everything is an object then
7 | numbers are objects. If "doing things" means operating with methods by the way
8 | of calling them, then what would `+` be? A method of course.
9 |
10 | But if we call methods on objects using that dot `.` notation, then where are
11 | the dots in `2 + 3 * 4`?
12 |
13 | The trick is: Ruby adds them for you, silently. If you write the following code:
14 |
15 | ```ruby
16 | number = 2 + 3 * 4
17 | ```
18 |
19 | Then Ruby will translate this to the following:
20 |
21 | ```ruby
22 | number = 2.+(3.*(4))
23 | ```
24 |
25 | Fun, isn't it? These operators are all methods on numbers, and they can be
26 | called just like any other method. (The same is true for lots of other
27 | operators, as you can see in IRB, when you run `1.methods.sort`.) The code
28 | above is valid Ruby code, and both lines do exactly the same.
29 |
30 | Ruby just adds a little bit of syntax in order to make it easier to read and
31 | write for us: It allows us to write `number = 2 + 3 * 4` instead of `number =
32 | 2.+(3.*(4))`, which is a pretty nasty thing to type.
33 |
34 | This is something called "syntax sugar", because it makes the language more
35 | sweet (no kidding).
36 |
37 | By the way, this works the same way for other things too.
38 |
39 | For example, you have learned about the array and hash syntax that uses square
40 | brackets `[]` for reading and writing.
41 |
42 | Ruby translates this code:
43 |
44 | ```ruby
45 | array = [1, 2, 3]
46 | array[3] = 4
47 | puts array[3]
48 |
49 | hash = { :one => 'eins', :two => 'zwei' }
50 | hash[:three] = 'drei'
51 | puts hash[:three]
52 | ```
53 |
54 | to these method calls:
55 |
56 | ```ruby
57 | array = [1, 2, 3]
58 | array.[]=(3, 4)
59 | puts(array.[](3))
60 |
61 | hash = { :one => 'eins', :two => 'zwei' }
62 | hash.[]=(:three, 'drei')
63 | puts(hash.[](:three))
64 | ```
65 |
66 | Knowing this can be useful when you want to write classes that look and feel
67 | similar to arrays or hashes, but behave differently.
68 |
--------------------------------------------------------------------------------
/source/70-bonus.md:
--------------------------------------------------------------------------------
1 | # Bonus Chapters
2 |
--------------------------------------------------------------------------------
/source/70-bonus/01-top_level.md:
--------------------------------------------------------------------------------
1 | # Top-level object
2 |
3 | So, we've learned that objects come with lots of methods attached to them. And
4 | we've seen how we can use them to do interesting things with the object, by the
5 | way of calling these methods.
6 |
7 | Now, if you pop into `irb`, or if you write the following code into an otherwise
8 | empty Ruby file, this works:
9 |
10 | ```ruby
11 | $ irb
12 | > is_a?(Object)
13 | true
14 | > methods
15 | [:to_s, :inspect, ... ]
16 | ```
17 |
18 | So, as you can see we can use some methods in Ruby without even defining an
19 | object at all: They're already there. And the method `is_a?` tells us that this
20 | already is an object ... whatever "this" is.
21 |
22 | What's up with that?
23 |
24 | This is something that pretty much blows some people's minds, confuses the heck
25 | out of others, while yet others don't even notice or think about it at all. It
26 | is also something, that, when you ask around on your local Ruby meetup, very
27 | few people can explain in a satisfying, and clear way. And neither do we, yet.
28 |
29 | Let's still try.
30 |
31 | Whenever you open IRB and it presents that prompt to you, or when you create a
32 | new, empty Ruby file ... Ruby will not only execute your code: Before she does
33 | she first creates an empty, anonymous Object, and kind of places you inside of
34 | it.
35 |
36 | This empty Object kind of seems invisible, and it seems that those methods
37 | that we can define in this scope (space) were somehow "standing alone". In fact
38 | they aren't. They're defined on this empty, anonymous Object that we usually
39 | don't see.
40 |
41 | This Object often is referred to as the *top-level scope* in Ruby.
42 |
43 |
44 | The top-level scope is an empty, anonymous object. All Ruby code starts in here.
45 |
46 |
47 | Confusing? Yeah. Don't worry. This is something many Ruby programmers do and
48 | use everyday without ever asking the question why it works, exactly.
49 |
50 | Hopefully some of this will become more clear once you've written your
51 | own methods and classes.
52 |
--------------------------------------------------------------------------------
/source/70-bonus/03-other_methods.md:
--------------------------------------------------------------------------------
1 | # Lots of other methods
2 |
3 | If you look at the methods that are defined on strings and arrays (e.g. run
4 | `[].methods.sort` or `{}.methods.sort` in IRB), then you'll find quite a bunch
5 | of method names that look like they are doing exactly what their names
6 | describe.
7 |
8 | For example, some of the things you can do with strings are:
9 |
10 | * `"a string".capitalize` returns `"A string"`, with the first letter uppercased.
11 | * `"a string".length` returns `8`, which is the length of the string.
12 | * `"a string".start_with?("a")` returns `true`, because the string starts with an `"a"`.
13 | * `"a string".include?("s")` returns `true`, because the string contains the character `"s"`.
14 |
15 | Some examples for useful methods on arrays are:
16 |
17 | * `[5, 1, 3].sort` returns another array, with the elements sorted: `[1, 3, 5]`.
18 | * `[5, 1, 3].size` returns `3`, the number of elements in the array.
19 | * `[1, 1, 1, 2].uniq` returns a new array with duplicate elements removed: `[1, 2]`.
20 | * `[1, 2, 3].join(", ")` returns a string `"1, 2, 3"`.
21 | * `[1, 2, 3].include?(2)` returns true because the array contains the number `2`.
22 |
23 | How do you find all these methods?
24 |
25 | The quickest way to find a certain method for an object often is to just ask
26 | Google: "ruby array sort". That will point you to the Ruby documentation.
27 | Another way is to read through all the methods for the class on the respective
28 | Ruby documentation page. And of course, you can also read through the method
29 | names returned by `[1, 2, 3].methods.sort`.
30 |
--------------------------------------------------------------------------------
/source/70-bonus/04-questions_commands.md:
--------------------------------------------------------------------------------
1 | # Questions and commands
2 |
3 | Generally speaking, methods play one of two roles: They either answer a question,
4 | or they perform a command.
5 |
6 | For example, if we have a `user` object, and users have a name, then we would
7 | ask the user object for its name by calling the method `name`: `user.name`
8 | would return the user's name. Arrays know their size (how many elements they
9 | have), so we can ask an array: `[1, 2, 3].size` will return `3`.
10 |
11 | Another example is the method `sort` on arrays. This method does not actually
12 | sort the array that it is called on. Instead it returns a *new* array with the
13 | same values, but in a sorted order:
14 |
15 | ```ruby
16 | array = [3, 2, 1]
17 | p array.sort
18 | p array
19 | ```
20 |
21 | This will output `[1, 2, 3]` and then `[3, 2, 1]`. So we see that the original
22 | array is still the same.
23 |
24 | Often questions need another bit of information passed. E.g., we can ask
25 | a string *Do you start with this character?*, and we'll need to pass the
26 | character that we are talking about: `"a string".start_with?("a")`. The answer
27 | to this question will be `true`. Or if we ask an array if it includes a certain
28 | element, then of course we need to pass that element, as in `[1, 2,
29 | 3].include?(1)`
30 |
31 | The other role that a method can play is being responsible for executing a
32 | certain command.
33 |
34 | For example in Rails objects that can be stored to the database have a method
35 | `save`. Of course, the purpose of this method is to save the object to the
36 | database. E.g. `user.save` would save some changes that we've made to the user
37 | before, like, maybe we have given them a new password.
38 |
39 | Another example is the method `sort!` on arrays. Different from the method
40 | `sort` (without an exclamation mark), this method tells the array to sort
41 | itself:
42 |
43 | ```ruby
44 | array = [3, 2, 1]
45 | array.sort!
46 | p array
47 | ```
48 |
49 | If you run this code, then it will print out `[1, 2, 3]`: the array is now
50 | sorted.
51 |
52 | Another example for a method that is a command is the method `puts`. All it
53 | does is print something to the screen, and it always returns `nil`.
54 |
55 | Whenever you think about adding a new method to your code it makes sense to
56 | think about the role the method should have. Is it a question? Or a command?
57 |
--------------------------------------------------------------------------------
/source/70-bonus/12-write_new_method.md:
--------------------------------------------------------------------------------
1 | # Writing a new method
2 |
3 | As programmers we like to split up our tasks, and do one thing after another.
4 | This allows us to focus on one small task, and once we've solved it, we move on
5 | to the next one.
6 |
7 | When you need to add some new functionality to your program you'll often
8 | find yourself thinking "I should add a method for this": methods add behaviour.
9 |
10 | Now, the first thing you should ask yourself is: "What is it that this method
11 | should do?" The answer to this gives you a hint for a good method name.
12 |
13 | Let's say you are working on an application that deals with emails, and the
14 | thing you are trying to accomplish is formatting an email. So your method name
15 | can be `format_email`.
16 |
17 | With this first task solved, knowing the method name, you can already go ahead
18 | and write down the method definition:
19 |
20 | ```ruby
21 | def format_email
22 | end
23 | ```
24 |
25 | While this is a pretty useless method, since it does nothing at all, it already
26 | *is* a valid method. So that's good progress already: you've made the first
27 | step.
28 |
29 | The next question to ask is: "Does this method need to be given any information
30 | in order to do its thing?" The answer to this question specifies the method's
31 | arguments list.
32 |
33 | In our example, the answer probably is that, in order to format an email, it
34 | needs the email.
35 |
36 | So you can now add the argument list to the method:
37 |
38 | ```ruby
39 | def format_email(email)
40 | end
41 | ```
42 |
43 | With these two things solved you can now start thinking about implementing
44 | the method body. How can you transform the email into some formatted text?
45 |
46 | You'd add a new line between `def` and `end`, and make sure it's indented by
47 | two spaces (hit `tab`, unless your editor does it for you), and start focussing
48 | on the code that makes up the method body:
49 |
50 | ```ruby
51 | def format_email(email)
52 | ...
53 | end
54 | ```
55 |
56 | You see how we've split up the task of writing a new method into three smaller
57 | tasks, and worked on each one of them after another.
58 |
59 | Even though this might seem trivial at first, we recommend you get into this
60 | habit, too.
61 |
62 | Btw, good editors help you format things. For example, when you are on a
63 | line that starts with `def something`, and at the end of the line hit return,
64 | Sublime will already indent the next line for you by 2 spaces. If you now type
65 | `end`, then Sublime will notice that you are closing the method, and outdent
66 | it again, so `def` and `end` sit on the same level. Smart, isn't it?
67 |
68 | Also, you'll notice that when you type an opening parenthesis `(`, then Sublime
69 | will add a closing one `)` too, but keep your cursor placed between them, so
70 | you can type the argument list where it belongs.
71 |
72 |
73 | Exercises: Now would be a good time to do some of the [exercises on
74 | methods](/exercises/methods_1.html).
75 |
--------------------------------------------------------------------------------
/source/70-bonus/13-arguments_parameters.md:
--------------------------------------------------------------------------------
1 | # Terminology: Arguments vs Parameters
2 |
3 | We should mention that we are slightly simplifying terminology here. We
4 | conflate two terms that normally would be defined separately: We simply use the
5 | term "argument" for both the variable names that are defined in the arguments
6 | list of the method definition, and the value that is passed as part of the
7 | method call.
8 |
9 | In programming, normally the "argument list" is called a "parameter list"
10 | instead, and a single name on it is called a "parameter". On the other hand,
11 | only the objects passed when calling the method are referred to as "arguments".
12 |
13 | E.g. in the code ...
14 |
15 | ```ruby
16 | def add_two(number)
17 | number + 2
18 | end
19 |
20 | puts add_two(3)
21 | ```
22 |
23 | ... the word `number` in the first line is a "parameter", whereas `3` in the
24 | last line is an "argument".
25 |
26 | We found making this distinction in our beginners classes unnecessarily
27 | confusing, and thus ignore it. We simply call both these things "arguments",
28 | and point out that they create a local variable inside of the method body.
29 |
30 | So, now you know :)
31 |
--------------------------------------------------------------------------------
/source/80-advanced.md:
--------------------------------------------------------------------------------
1 | # Advanced Topics
2 |
--------------------------------------------------------------------------------
/source/80-advanced/03-private_methods.md:
--------------------------------------------------------------------------------
1 | # Private methods
2 |
3 | Remember how we said that instance variables store data that is "private" to
4 | the object? Instance variables are only made accessible to the outside world
5 | (we say "it is exposed") if we add attribute accessors to the class.
6 |
7 | In the same way classes sometimes want to keep certain methods private: methods
8 | that aren't supposed to be called from outside of the object. Only the object
9 | itself is supposed to use them internally, from other methods.
10 |
11 | Imagine I am an instance of a class `ItalianRestaurant`, and I have a method
12 | `pizza`, which is supposed to return an instance of the class `Pizza`.
13 |
14 | When you approach me, and call the method `pizza` (i.e. ask me to bring a
15 | pizza) then I'll know what to do, and how to do it. I'll get some prepared
16 | pizza dough from somewhere, some tomato sauce, vegetables and other stuff from
17 | somewhere else, prepare the pizza, bake it, put it on a nice plate, and finally
18 | give (return) it to you.
19 |
20 | However, you don't really care about any of these details. You are hungry, and
21 | just want the pizza. All the exact steps involved are something that I keep
22 | private to me, and maybe they've been our family's best kept secret for
23 | generations.
24 |
25 | This is pretty much how objects work, too. The Italian restaurant object
26 | exposes some stuff to the outer world (you), and keeps other things private.
27 | They'll let you order a pizza, and other things. But they won't tell you the
28 | exact ingredients of their tomato sauce, or how they manage to make this damn
29 | great pizza dough.
30 |
31 | In our `Person` example it makes sense to make the method `encrypt` private.
32 |
33 | Currently, if you run the following code it will execute just fine, even though
34 | it makes little sense:
35 |
36 | ```ruby
37 | person = Person.new("Ada")
38 | p person.encrypt("some other secret")
39 | ```
40 |
41 | Why would a person encrypt some arbitrary string for someone else, and return
42 | it? This is something that the person object should keep private. The
43 | restaurant wouldn't turn flour, water, olive oil and other ingredients into
44 | pizza dough for everyone else either.
45 |
46 | We can make the method `encrypt` private like so:
47 |
48 | ```ruby
49 | module Encryption
50 | private
51 |
52 | def encrypt(string)
53 | Digest::SHA2.hexdigest(string)
54 | end
55 | end
56 | ```
57 |
58 | The keyword `private` tells Ruby that all methods defined from now on, are
59 | supposed to be private. They can be called from within the object (from other
60 | methods that the class defines), but not from outside.
61 |
62 | If you now try to call the method it will raise an error:
63 |
64 | ```ruby
65 | person = Person.new("Ada")
66 | p person.encrypt("super secret")
67 | ```
68 |
69 | This will print the error message:
70 |
71 | ```
72 | private method `encrypt' called for #
73 | ```
74 |
75 | Nice. Does this make sense?
76 |
--------------------------------------------------------------------------------
/source/80-advanced/04-procs.md:
--------------------------------------------------------------------------------
1 | # Procs
2 |
3 | TBD
4 |
--------------------------------------------------------------------------------
/source/80-advanced/05-yield.md:
--------------------------------------------------------------------------------
1 | # Yield
2 |
3 | TBD
4 |
--------------------------------------------------------------------------------
/source/90-exercises.md:
--------------------------------------------------------------------------------
1 | # Exercises (old)
2 |
3 | These exercises are an outdated set of exercises that need to be ported and
4 | adjusted in order to reflect the current order of topics in our book.
5 |
6 | Many of them at the moment assume things early on that only are explained
7 | later in the book.
8 |
--------------------------------------------------------------------------------
/source/90-exercises/01-numbers.md:
--------------------------------------------------------------------------------
1 | # Working with Numbers
2 |
3 | In order to start `irb` open your terminal and type `irb`, then hit the
4 | `return` key (`enter`). In order to quit `irb` again (and get back to your
5 | system shell prompt) you can type `exit` or press `ctrl-d`, which does the
6 | same.
7 |
8 | ## Exercise 1.1
9 |
10 | In `irb`, calculate:
11 |
12 | * How many hours are in a year.
13 | * How many minutes are in a decade?
14 | * How many seconds old are you?
15 |
16 | ## Exercise 1.2
17 |
18 | What do you think happens when you combine the following floats and integers?
19 |
20 | Try computing these in `irb`:
21 |
22 | * `3.0 / 2`
23 | * `3 / 2.0`
24 | * `4 ** 2.0`
25 | * `4.1 % 2`
26 |
27 | Is the result a float or an integer?
28 |
29 | ## Exercise 1.3
30 |
31 | Methods are a way of "doing something with an object". E.g. in Ruby, numbers
32 | have two methods that allow you to check whether the number is odd or even.
33 |
34 | Look through the documentation for integer
35 | numbers (called `Fixnum`) and find the methods that tell if a number is odd or
36 | even.
37 |
38 | ## Exercise 1.4
39 |
40 | In `irb`, use these methods to find out if certain numbers are odd or even.
41 | Numbers like `0, 1, 2, 99, -502` etc.
42 |
43 |
44 | You can use a method by appending a dot . and then the method name
45 | to the object. E.g. -99.abs uses (we also say: "calls") the method
46 | abs on the number -99.
47 |
48 |
49 | Try for yourself what it does, and google for "ruby abs" to find
50 | [the documentation](http://ruby-doc.org/core-2.0/Numeric.html#method-i-abs)
51 | for this method.
52 |
--------------------------------------------------------------------------------
/source/90-exercises/02-strings.md:
--------------------------------------------------------------------------------
1 | # Working with Strings
2 |
3 | In order to start `irb` open your terminal and type `irb`, then hit the
4 | `return` key (`enter`). In order to quit `irb` again (and get back to your
5 | system shell prompt) you can type `exit` or press `ctrl-d`, which does the
6 | same.
7 |
8 | ## Exercise 2.1
9 |
10 | What do you think this will do?
11 |
12 | ```ruby
13 | $ irb
14 | > "hello".length + "world".length
15 | ```
16 |
17 | Try it yourself.
18 |
19 | ## Exercise 2.3
20 |
21 | Skim through the [documentation for strings](http://www.ruby-doc.org/core-2.1.4/String.html)
22 | in the Ruby documentation, and look for a method that prepends one string
23 | to another string.
24 |
25 | Using that method prepend the string `"Learning "` to the string `"Ruby"`
26 |
27 | Show solution
28 |
29 | ## Exercise 2.4
30 |
31 | Skim through the [documentation for strings](http://www.ruby-doc.org/core-2.1.4/String.html)
32 | in the Ruby documentation, and look for a method that removes characters
33 | from a string.
34 |
35 | Using that method turn the string `"Learning Ruby"` into the string `"Lrnng Rb"`.
36 |
37 | Show solution
38 |
39 | ## Exercise 2.5
40 |
41 | Find out how to convert the string `"1.23"` into the number `1.23`.
42 |
43 | You can either, again, skim the documentation page for strings, or google for
44 | "ruby convert string to number".
45 |
46 | Then also find out what method can be used to turn the string `"1"` into the
47 | number `1` (remember floats and integers are different kinds of numbers).
48 |
49 | Confirm that you have found the right methods by trying them in `irb`.
50 |
51 | Show solution
52 |
53 | ## Exercise 2.6
54 |
55 | There is a method that allows to justify a string, and padding it with another
56 | string.
57 |
58 | Find that method and use it on the string `"Ruby"` together with `"<3"` so that
59 | you get the following string back:
60 |
61 | ```ruby
62 | "Ruby<3<3<3"
63 | ```
64 |
65 | We'll admit that this is a rather creative usage of this method. Normally you'd
66 | use it to align strings to columns (e.g. so that they line up nicely when you
67 | format a table). You'll use this method in other exercises later on.
68 |
69 | Show solution
70 |
71 |
--------------------------------------------------------------------------------
/source/90-exercises/03-arrays_1.md:
--------------------------------------------------------------------------------
1 | # Working with Arrays (1)
2 |
3 | Before you get started, make sure you have your text editor and terminal open,
4 | and you have navigated to your exercises directory in the terminal. E.g. `cd
5 | ~/ruby-for-beginners/exercises`.
6 |
7 | ## Exercise 3.1
8 |
9 | Create a new, empty file. Save it as `arrays_1-1.rb`. Fill in the following
10 | line:
11 |
12 | ```ruby
13 | numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
14 | # your code goes here
15 | ```
16 |
17 | So that, when you run your code (run `ruby arrays_1-1.rb`), you get the
18 | following output:
19 |
20 | ```ruby
21 | 5
22 | ```
23 |
24 | Show solution
25 |
26 | ## Exercise 3.2
27 |
28 | Copy your file to a new file: `cp arrays_1-1.rb arrays_1-2.rb`, then open this
29 | new file.
30 |
31 | Add another line *before the line that you just added*, so that, when you run
32 | your code, you get the following output:
33 |
34 | ```ruby
35 | 99
36 | ```
37 |
38 | Show solution
39 |
40 | ## Exercise 3.3
41 |
42 | Make a new file `arrays_1-3.rb`, and fill in the following line:
43 |
44 | ```ruby
45 | numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
46 | # your code goes here
47 | p numbers
48 | ```
49 |
50 | So that you get the following output:
51 |
52 | ```ruby
53 | [2, 4, 6, 8, 10]
54 | ```
55 |
56 |
57 | Read the documentation for the method select that you can use on arrays
58 | on the Ruby documentation
59 |
60 |
61 | Show solution
62 |
63 | ## Exercise 3.4
64 |
65 | Again, copy your last file to a new file: `cp arrays_1-3.rb arrays_1-4.rb`,
66 | then open this new file.
67 |
68 | Now change the code that you just added so that you get the following output:
69 |
70 | ```ruby
71 | [10, 8, 6, 4, 2]
72 | ```
73 |
74 |
75 | The method select that you used in the last exercise returns an array.
76 | On this array (the return value) you can use another method, by, again, just
77 | appending a dot . and the method name to it, i.e., to the end of the line.
78 |
79 |
80 |
81 | There is another method that reverses the order of the array. You can
82 | find it by googling for "ruby array reverse".
83 |
84 |
85 | Show solution
86 |
87 | ## Exercise 3.5
88 |
89 | Again, copy your last file to a new file: `cp arrays_1-4.rb arrays_1-5.rb`,
90 | then open this new file.
91 |
92 | Now change your code so that you get the following output:
93 |
94 | ```ruby
95 | [10, 8, 4, 2]
96 | ```
97 |
98 | Bonus: Find at least three different solutions for this last change.
99 |
100 | Show solution
101 |
102 |
103 |
--------------------------------------------------------------------------------
/source/90-exercises/04-hashes_1.md:
--------------------------------------------------------------------------------
1 | # Working with Hashes (1)
2 |
3 | Before you get started, make sure you have your text editor and terminal open,
4 | and you have navigated to your exercises directory in the terminal. E.g. `cd
5 | ~/ruby-for-beginners/exercises`.
6 |
7 |
8 | ## Exercise 4.1
9 |
10 | Make a new file `hashes_1-1.rb`, and fill in the following line:
11 |
12 | ```ruby
13 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
14 | # your code goes here
15 | ```
16 |
17 | So that it prints out `dos`.
18 |
19 | Show solution
20 |
21 |
22 | ## Exercise 4.2
23 |
24 | Make a new file `hashes_1-2.rb`, and fill in the following line:
25 |
26 | ```ruby
27 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
28 | # your code goes here
29 | puts dictionary[:four]
30 | ```
31 |
32 | So that it prints out `cuatro`.
33 |
34 | Show solution
35 |
36 |
37 | ## Exercise 4.3
38 |
39 | Copy that file to a new file `cp hashes_1-2.rb hashes_1-3.rb`, and change your
40 | code so that it prints out the following.
41 |
42 | ```
43 | Cuatro
44 | ```
45 |
46 |
47 | There's a method that upcases the first letter of a string. Find it by
48 | googling for "ruby string upcase first letter".
49 |
50 |
51 | Show solution
52 |
53 |
54 | ## Exercise 4.4
55 |
56 | There is a method on hashes that allows to check if a certain key is defined on
57 | the hash. Find that method by googling for "ruby hash key defined".
58 |
59 | Try this method in `irb` by creating a hash like the one above, calling the
60 | method and passing keys like `:one`, `:two`, `:four`, and `:ten`.
61 |
62 | Show solution
63 |
64 |
65 | ## Exercise 4.5
66 |
67 | There is a method on hashes that flips keys and values. Find that method on the
68 | [Ruby documentation about hashes](http://www.ruby-doc.org/core-2.2.0/Hash.html)
69 |
70 | Make a new file `hashes_1-5.rb`, and fill in the following line using that
71 | method:
72 |
73 | ```ruby
74 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
75 | # your code goes here
76 | ```
77 |
78 | This should then output:
79 |
80 | ```
81 | { 'uno' => :one, 'dos' => :two, 'tres' => :three }
82 | ```
83 |
84 | Show solution
85 |
--------------------------------------------------------------------------------
/source/90-exercises/05-methods_1.md:
--------------------------------------------------------------------------------
1 | # Defining methods
2 |
3 | ## Exercise 5.1
4 |
5 | Write a method `greet` that takes a name, prepends `"Hello "`, and appends an
6 | exclamation mark `"!"`:
7 |
8 | ```ruby
9 | def greet(name)
10 | # your code goes here
11 | end
12 |
13 | puts greet("Ada")
14 | ```
15 |
16 | This should print out `Hello Ada!`.
17 |
18 | Show solution
19 |
20 |
21 | ## Exercise 5.2
22 |
23 | Once you've implemented the method this should print out: `Hello Ada!`.
24 |
25 | Now change your method so that instead of always using `"Hello "` it picks a
26 | random string from the array `["Hello", "Hi", "Ohai", "ZOMG"]`.
27 |
28 | Every time you run the program it should print out either `"Hello Ada!"`, `"Hi
29 | Ada!"`, `"Ohai Ada!"`, or `"ZOMG Ada!"`.
30 |
31 |
32 | The method shuffle on arrays does, well, shuffle the array :) That
33 | means it changes the order of the elements in the array in a random way.
34 |
35 |
36 | Show solution
37 |
38 |
39 | ## Exercise 5.3
40 |
41 | Write a method that converts a distance (a number) from miles to kilometers:
42 |
43 | ```ruby
44 | def miles_to_kilometers(miles)
45 | # your code goes here
46 | end
47 |
48 | puts miles_to_kilometers(25)
49 | ```
50 |
51 | This should print out:
52 |
53 | ```
54 | 40.2336
55 | ```
56 |
57 | Show solution
58 |
59 |
60 | ## Exercise 5.4
61 |
62 | Write a method `leap_year?` that takes a year (a number), and calculates if it is a leap year.
63 |
64 | ```ruby
65 | def leap_year?(year)
66 | # your code goes here
67 | end
68 |
69 | p leap_year?(2012)
70 | p leap_year?(2015)
71 | ```
72 |
73 | This should print out:
74 |
75 | ```
76 | true
77 | false
78 | ```
79 |
80 | Hint: The operator `%` returns the rest of a division. E.g. `14 % 3` returns `2`.
81 |
82 | Bonus: Also make it so that the method returns `true` for the year `2000` and
83 | `false` for `1900` ... because that's really the definition of leap years.
84 |
85 | Show solution
86 |
87 |
--------------------------------------------------------------------------------
/source/90-exercises/07-nested_arrays.md:
--------------------------------------------------------------------------------
1 | # Working with Nested Arrays
2 |
3 | Note: At the moment these exercises require reading up until "Block return values".
4 | You should know how to use the method `collect` on arrays.
5 |
6 | Before you get started, make sure you have your text editor and terminal open, and
7 | you have navigated to your exercises directory in the terminal. E.g. `cd
8 | ~/ruby-for-beginners/exercises`.
9 |
10 | ## Exercise 7.1
11 |
12 | Make a new file `nested_arrays-1.rb`, and fill in the following line:
13 |
14 | ```ruby
15 | numbers = [
16 | [1, 2, 3],
17 | [4, 5, 6],
18 | [7, 8, 9]
19 | ]
20 | # your code goes here
21 | p sums
22 | ```
23 |
24 | So that you get the following output:
25 |
26 | ```ruby
27 | [6, 15, 24]
28 | ```
29 |
30 | Show solution
31 |
32 |
33 | ## Exercise 7.2
34 |
35 | Make a new file `nested_arrays-2.rb`, and fill in the following line:
36 |
37 | Fill in the following line
38 |
39 | ```ruby
40 | numbers = [
41 | [1, 2, 3],
42 | [2, 2, 2],
43 | [3, 2, 1]
44 | ]
45 | # your code goes here
46 | lines.each { |line| puts line }
47 | ```
48 |
49 | So that you get the following output:
50 |
51 | ```
52 | * ** ***
53 | ** ** **
54 | *** ** *
55 | ```
56 |
57 | Show solution
58 |
59 |
--------------------------------------------------------------------------------
/source/90-exercises/08-hashes_2.md:
--------------------------------------------------------------------------------
1 | # Working with Hashes (2)
2 |
3 | ## Exercise 8.1
4 |
5 | Make a new file `hashes_2-1.rb`, and dd the following lines:
6 |
7 | ```ruby
8 | languages = {
9 | :de => 'German',
10 | :en => 'English',
11 | :es => 'Spanish',
12 | }
13 | dictionary = {
14 | :de => { :one => 'eins', :two => 'zwei', :three => 'drei' },
15 | :en => { :one => 'one', :two => 'two', :three => 'three' },
16 | :es => { :one => 'uno', :two => 'dos', :three => 'tres' }
17 | }
18 | ```
19 |
20 | Now, at the end of the file, add code that prints out the following:
21 |
22 | ```
23 | In German, eins means one, zwei means two, drei means three.
24 | In Spanish, uno means one, duo means two, tres means three.
25 | ```
26 |
27 | Show solution
28 |
29 |
30 | ## Exercise 8.2
31 |
32 | Now, in a new file `hashes_2-2.rb`, with the same hashes from above, add code
33 | that prints out the following table:
34 |
35 | ```
36 | de eins zwei drei
37 | en one two three
38 | es uno dos tres
39 | ```
40 |
41 | Show solution
42 |
43 |
44 | ## Exercise 8.3
45 |
46 | Copy your file to a new file `cp hashes_2-2.rb hashes_2-3.rb` and change your
47 | code so that it aligns the table columns:
48 |
49 | ```
50 | de eins zwei drei
51 | en one two three
52 | es uno dos tres
53 | ```
54 |
55 | Show solution
56 |
57 |
58 | ## Exercise 8.4
59 |
60 | Copy your file to a new file `cp hashes_2-3.rb hashes_2-4.rb` and change your
61 | code so that it adds delimiters:
62 |
63 | ```
64 | | de | eins | zwei | drei |
65 | | en | one | two | three |
66 | | es | uno | dos | tres |
67 | ```
68 |
69 | Show solution
70 |
71 |
--------------------------------------------------------------------------------
/source/90-exercises/10-email.md:
--------------------------------------------------------------------------------
1 | # The Email Class
2 |
3 | ## Exercise 10.1
4 |
5 | In a new file `email_1.rb` write a class `Email` that has a `subject`,
6 | `date`, and `from` attribute. Make it so that these attributes can be populated
7 | through `new` and `initialize`.
8 |
9 | The following code
10 |
11 | ```ruby
12 | class Email
13 | # fill in this class body
14 | end
15 |
16 | email = Email.new("Homework this week", "2014-12-01", "Ferdous")
17 |
18 | puts "Date: #{email.date}"
19 | puts "From: #{email.from}"
20 | puts "Subject: #{email.subject}"
21 | ```
22 |
23 | should then output the following:
24 |
25 | ```
26 | Date: 2014-12-01
27 | From: Ferdous
28 | Subject: Homework this week
29 | ```
30 |
31 | Show solution
32 |
33 | ## Exercise 10.2
34 |
35 | Once you have this class, copy your file to `email_2.rb`.
36 |
37 | Change your class so that the `initialize` method now takes a `subject` string,
38 | and a `headers` hash. This is then more in line with how actual emails are
39 | stored in the real world: the values `date` and `from` are stored on a hash,
40 | which is called the "email headers".
41 |
42 | Doing so, in the code above the only line you should change is the one that
43 | instantiates the email object, which should now read:
44 |
45 | ```ruby
46 | email = Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Ferdous" })
47 | ```
48 |
49 | Your program should now still produce the same output.
50 |
51 | Show solution
52 |
--------------------------------------------------------------------------------
/source/90-exercises/11-mailbox.md:
--------------------------------------------------------------------------------
1 | # The Mailbox Class
2 |
3 | ## Exercise 11.1
4 |
5 | In a new file `mailbox-1.rb` Write a class that has a `name` and `emails`
6 | attribute. Make it so that the these attributes can be populated through the
7 | `initialize` method (`name` being a string, and `emails` being an array of
8 | `Email` instances).
9 |
10 | The following code
11 |
12 | ```ruby
13 | class Email
14 | # your class from the last exercise
15 | end
16 |
17 | class Mailbox
18 | # fill in this class body
19 | end
20 |
21 | emails = [
22 | Email.new("Homework this week", { :date => "2014-12-01", :from => "Ferdous" }),
23 | Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Dajana" }),
24 | Email.new("Re: Homework this week", { :date => "2014-12-02", :from => "Ariane" })
25 | ]
26 | mailbox = Mailbox.new("Ruby Study Group", emails)
27 |
28 | mailbox.emails.each do |email|
29 | puts "Date: #{email.date}"
30 | puts "From: #{email.from}"
31 | puts "Subject: #{email.subject}"
32 | puts
33 | end
34 | ```
35 |
36 | should then output the following:
37 |
38 | ```
39 | Date: 2014-12-01
40 | From: Ferdous
41 | Subject: Homework this week
42 |
43 | Date: 2014-12-01
44 | From: Dajana
45 | Subject: Keep on coding! :)
46 |
47 | Date: 2014-12-02
48 | From: Arianne
49 | Subject: Re: Homework this week
50 | ```
51 |
52 | Show solution
53 |
--------------------------------------------------------------------------------
/source/90-exercises/12-mailbox_text.md:
--------------------------------------------------------------------------------
1 | # The Mailbox Text Formatter
2 |
3 | The mailbox text formatter exercise is a milestone in the beginners group
4 | curriculum, and it may take a little bit longer to complete it. That is fine,
5 | and, to some extent, the point :)
6 |
7 | ## Exercise 12.1
8 |
9 | Make a new file `mailbox_text-1.rb`. Fill in and complete the following
10 | class definitions:
11 |
12 | ```ruby
13 | class Email
14 | # your class from the last exercise
15 | end
16 |
17 | class Mailbox
18 | # your class from the last exercise
19 | end
20 |
21 | class MailboxTextFormatter
22 | # fill in this class body
23 | end
24 |
25 | emails = [
26 | Email.new("Homework this week", { :date => "2014-12-01", :from => "Ferdous" }),
27 | Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Dajana" }),
28 | Email.new("Re: Homework this week", { :date => "2014-12-02", :from => "Ariane" })
29 | ]
30 | mailbox = Mailbox.new("Ruby Study Group", emails)
31 | formatter = MailboxTextFormatter.new(mailbox)
32 |
33 | puts formatter.format
34 | ```
35 |
36 | Your goal is to complete the code in a way so it outputs the following:
37 |
38 | ```
39 | Mailbox: Ruby Study Group
40 |
41 | +------------+---------+------------------------+
42 | | Date | From | Subject |
43 | +------------+---------+------------------------+
44 | | 2014-12-01 | Ferdous | Homework this week |
45 | | 2014-12-01 | Dajana | Keep on coding! :) |
46 | | 2014-12-02 | Ariane | Re: Homework this week |
47 | +------------+---------+------------------------+
48 | ```
49 |
50 | You are allowed to add as many methods to the classes `Email`, `Mailbox` and
51 | `MailboxTextFormatter` as you deem useful. In your final solution you are not
52 | allowed to change any of the code outside (after) the class definitions. For
53 | debugging purposes, you can, of course, change all the code you want :)
54 |
55 | If you do this exercise in one of our study groups then best do it together
56 | with someone else. We found pairs to work best, and a three person team would
57 | be better than doing it on your own.
58 |
59 | Try to come up with a working solution first. It doesn't matter how elegant,
60 | generic, or pretty it is. Whatever produces the required output is fine for a
61 | first solution.
62 |
63 | Then, later, look at your code, and try to improve it by cleaning up everything
64 | that you don't like, or deam ugly.
65 |
66 | Eventually, one goal to aim for would be: Adding another column to the table
67 | only requires mimimal changes, e.g. changes to one or two places in your
68 | formatter class.
69 |
70 | Show solution
71 |
--------------------------------------------------------------------------------
/source/90-exercises/14-mailbox_file.md:
--------------------------------------------------------------------------------
1 | # Storing our HTML to a File
2 |
3 | ## Exercise 14.1
4 |
5 | In this exercise our goal is to store the generated HTML for our mailbox to a
6 | file, so that we can finally view it in an actual browser.
7 |
8 | Your objective is to write a file (using Ruby) that contains all the HTML
9 | from the last exercise.
10 |
11 | Building on the last exercise, copy your file to a new file `cp mailbox_html-1.rb
12 | mailbox_file-1.rb` and change the last line:
13 |
14 | Instead of passing the HTML to `puts` you should be passing it to a different
15 | method, so that running your program writes the HTML file that we are after.
16 | In order to find that method try googling for "ruby write file". Call this
17 | file `emails.html`.
18 |
19 | When you open this file in a text editor you should see the same HTML from
20 | the last exercise. When you open it in your browser it should look like this:
21 |
22 | 
23 |
24 | Show solution
25 |
--------------------------------------------------------------------------------
/source/91-exercises_2.md:
--------------------------------------------------------------------------------
1 | # Exercises
2 |
3 | If you haven't done the [try ruby](http://tryruby.org) course already, we
4 | recommend you do at least a couple of lessons over there too.
5 |
6 | Whenever you sit down to do some of the exercises in this book make sure you
7 | have your text editor and terminal open. In your terminal:
8 |
9 | * Create a new directory where you want to keep Ruby files for our exercises. For
10 | example: `~/ruby-for-beginners/exercises`. In
11 | order to create that directory in the terminal you can run: `mkdir
12 | ~/ruby-for-beginners/exercises`.
13 |
14 | * Then navigate to this directory: `cd ~/ruby-for-beginners/exercises`
15 |
16 | * In order to check if you are in the right directory you can always run:
17 | `pwd`. (That's short for *print working directory*, meaning, it prints the name
18 | of the current directory.)
19 |
20 | * In order to see all the files and subdirectories contained in the current
21 | directory you can run `ls`.
22 |
23 |
24 | Credits: The exercises 1.1, 1.2, and 2.1 are taken from
25 | Introduction to Ruby.
26 |
27 |
--------------------------------------------------------------------------------
/source/91-exercises_2/01-numbers.md:
--------------------------------------------------------------------------------
1 | # Working with Numbers
2 |
3 | In order to do these exercises you should have read at least the chapter about
4 | [built_in_classes/numbers.html].
5 |
6 | ## Exercise 1.1
7 |
8 | In `irb`, calcluate:
9 |
10 | * How many hours are in a year.
11 | * How many minutes are in a decade?
12 | * How many seconds old are you?
13 |
14 |
15 | To start irb open your terminal and type irb, then
16 | hit the return key (enter). To quit it (and get back
17 | to your system shell prompt) type exit or press ctrl-d.
18 |
19 |
20 | ## Exercise 1.2
21 |
22 | What do you think happens when you combine floats and integers the following
23 | in the following calculations?
24 |
25 | Try computing these in `irb`:
26 |
27 | * `3 / 2`
28 | * `3.0 / 2`
29 | * `3 / 2.0`
30 | * `4 * 2.0`
31 | * `0 + 1`
32 |
33 | Is the result a float or an integer?
34 |
35 | ## Exercise 1.3
36 |
37 | Try finding out what "modulo" means by asking Google.
38 |
39 | In Ruby (and many other languages) the operator for modulo is `%`.
40 |
41 | Try the following in `irb`:
42 |
43 | * `5 % 2`
44 | * `15 % 2`
45 | * `505 % 2`
46 |
47 | And:
48 |
49 | * `8 % 5`
50 | * `9 % 5`
51 | * `10 % 5`
52 | * `11 % 5`
53 |
54 | ## Exercise 1.4
55 |
56 | Methods are a way of "doing something with an object", and you'll learn a lot
57 | more about them in a few chapters.
58 |
59 | In Ruby, numbers have methods that allow you to check whether the number is odd
60 | or even.
61 |
62 | Look through the documentation for integer
63 | numbers and find the methods that tell if a number is odd or even.
64 |
65 | Look at the examples for some of the other methods on that page.
66 |
67 |
68 | You can use a method by appending a dot . and then the method name
69 | to the object. E.g. -99.abs uses (we also say: "calls") the method
70 | abs on the number -99.
71 |
72 |
73 | ## Exercise 1.5
74 |
75 | In `irb`, use these methods to find out if certain numbers are odd or even.
76 |
77 | Try a bunch of numbers like `0, 1, 2, 99, -502` etc.
78 |
79 | Try for yourself what it does, and google for "ruby number odd even" to find
80 | [the documentation](http://ruby-doc.org/core-2.2.2/Integer.html#method-i-odd-3F)
81 | for these methods.
82 |
83 | Show solution
84 |
--------------------------------------------------------------------------------
/source/91-exercises_2/02-strings.md:
--------------------------------------------------------------------------------
1 | # Working with Strings
2 |
3 | In order to do these exercises you should have read at least the chapter about
4 | [built_in_classes/strings.html].
5 |
6 | ## Exercise 2.1
7 |
8 | In `irb` try figuring out how to produce the following String: `"Ruby<3<3<3"`.
9 |
10 | Try using no more than two other String objects.
11 |
12 | Show solution
13 |
14 |
15 | To start irb open your terminal and type irb, then
16 | hit the return key (enter). To quit it (and get back
17 | to your system shell prompt) type exit or press ctrl-d.
18 |
19 |
20 | ## Exercise 2.2
21 |
22 | Look through the documentation for Strings.
23 |
24 | Do you spot any interesting methods?
25 |
26 | ## Exercise 2.3
27 |
28 | What do you think this will do?
29 |
30 | ```ruby
31 | $ irb
32 | > "hello".length + "world".length
33 | ```
34 |
35 | Try it yourself in `irb`.
36 |
37 | Show solution
38 |
39 | ## Exercise 2.4
40 |
41 | Look through the documentation for Strings,
42 | and find out how to convert the string `"1.23"` into the number `1.23`.
43 |
44 | If you can't find it, google for "ruby convert string to float".
45 |
46 | Then also find out what method can be used to turn the string `"1"` into the
47 | number `1` (remember floats and integers are different kinds of numbers).
48 |
49 | Confirm that you have found the right methods by trying them in `irb`.
50 |
51 | Show solution
52 |
53 |
--------------------------------------------------------------------------------
/source/91-exercises_2/04-hashes_1.md:
--------------------------------------------------------------------------------
1 | # Working with Hashes (1)
2 |
3 | In order to do these exercises you should have read at least the chapter about
4 | [built_in_classes/hashes.html].
5 |
6 |
7 | Make sure you have your text editor and terminal open, and you have navigated
8 | to your exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises.
9 |
10 |
11 | ## Exercise 4.1
12 |
13 | Make a new file `hashes_1-1.rb`, and fill in the following line:
14 |
15 | ```ruby
16 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
17 | # your code goes here
18 | ```
19 |
20 | ... so that it prints out `dos`.
21 |
22 | Show solution
23 |
24 |
25 | ## Exercise 4.2
26 |
27 | Make a new file `hashes_1-2.rb`, and fill in the following line:
28 |
29 | ```ruby
30 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
31 | # your code goes here
32 | puts dictionary[:four]
33 | ```
34 |
35 | ... so that it prints out `cuatro`.
36 |
37 | Show solution
38 |
39 |
40 | ## Exercise 4.3
41 |
42 | Copy that file to a new file `cp hashes_1-2.rb hashes_1-3.rb`, and change your
43 | code so that it prints out the following.
44 |
45 | ```
46 | Cuatro
47 | ```
48 |
49 |
50 | There's a method that upcases the first letter of a string. Find it by
51 | googling for "ruby string upcase first letter".
52 |
53 |
54 | Show solution
55 |
56 |
57 | ## Exercise 4.4
58 |
59 | There is a method on hashes that allows to check if a certain key is defined on
60 | the hash. Find that method by googling for "ruby hash key defined".
61 |
62 | Try this method in `irb` by creating a hash like the one above, calling the
63 | method and passing keys like `:one`, `:two`, `:four`, and `:ten`.
64 |
65 | Show solution
66 |
67 |
68 | ## Exercise 4.5
69 |
70 | There is a method on hashes that flips keys and values. Find that method on the
71 | [Ruby documentation about Hashes](http://www.ruby-doc.org/core-2.2.0/Hash.html)
72 |
73 | Make a new file `hashes_1-5.rb`, and fill in the following line using that
74 | method:
75 |
76 | ```ruby
77 | dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }
78 | # your code goes here
79 | ```
80 |
81 | This should then output:
82 |
83 | ```
84 | { 'uno' => :one, 'dos' => :two, 'tres' => :three }
85 | ```
86 |
87 | Show solution
88 |
--------------------------------------------------------------------------------
/source/91-exercises_2/99-notes.md:
--------------------------------------------------------------------------------
1 | # Working with Strings
2 |
3 | ## Exercise 2.3
4 |
5 | Skim through the [documentation for strings](http://www.ruby-doc.org/core-2.1.4/String.html)
6 | in the Ruby documentation, and look for a method that prepends one string
7 | to another string.
8 |
9 | Using that method prepend the string `"Learning "` to the string `"Ruby"`
10 |
11 | Show solution
12 |
13 | ## Exercise 2.4
14 |
15 | Skim through the [documentation for strings](http://www.ruby-doc.org/core-2.1.4/String.html)
16 | in the Ruby documentation, and look for a method that removes characters
17 | from a string.
18 |
19 | Using that method turn the string `"Learning Ruby"` into the string `"Lrnng Rb"`.
20 |
21 | Show solution
22 |
23 | ## Exercise 2.6
24 |
25 | There is a method that allows to justify a string, and padding it with another
26 | string.
27 |
28 | Find that method and use it on the string `"Ruby"` together with `"<3"` so that
29 | you get the following string back:
30 |
31 | ```ruby
32 | "Ruby<3<3<3"
33 | ```
34 |
35 | We'll admit that this is a rather creative usage of this method. Normally you'd
36 | use it to align strings to columns (e.g. so that they line up nicely when you
37 | format a table). You'll use this method in other exercises later on.
38 |
39 | Show solution
40 |
41 |
42 | # Working with Arrays (1)
43 |
44 | ## Exercise 3.3
45 |
46 | Make a new file `arrays_1-3.rb`, and fill in the following line:
47 |
48 | ```ruby
49 | numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
50 | # your code goes here
51 | p numbers
52 | ```
53 |
54 | So that you get the following output:
55 |
56 | ```ruby
57 | [2, 4, 6, 8, 10]
58 | ```
59 |
60 |
61 | Read the documentation for the method select that you can use on arrays
62 | on the Ruby documentation
63 |
64 |
65 | Show solution
66 |
67 | ## Exercise 3.5
68 |
69 | Again, copy your last file to a new file: `cp arrays_1-4.rb arrays_1-5.rb`,
70 | then open this new file.
71 |
72 | Now change your code so that you get the following output:
73 |
74 | ```ruby
75 | [10, 8, 4, 2]
76 | ```
77 |
78 | Bonus: Find at least three different solutions for this last change.
79 |
80 | Show solution
81 |
82 |
83 |
--------------------------------------------------------------------------------
/source/CNAME:
--------------------------------------------------------------------------------
1 | ruby-for-beginners.rubymonstas.org
2 |
--------------------------------------------------------------------------------
/source/assets/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/assets/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/source/assets/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/assets/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/source/assets/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/assets/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/source/assets/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/assets/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/source/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubymonsters/ruby-for-beginners/a4ded425e25a4f809267d41a644b3f944177548e/source/assets/images/favicon.png
--------------------------------------------------------------------------------
/source/assets/stylesheets/_fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'FontAwesome';
3 | src: url('../fonts/fontawesome-webfont.eot');
4 | src: url('../fonts/fontawesome-webfont.eot') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff') format('woff'), url('../fonts/fontawesome-webfont.ttf') format('truetype'), url('../fonts/fontawesome-webfont.svg') format('svg');
5 | font-weight: normal;
6 | font-style: normal;
7 | }
8 |
--------------------------------------------------------------------------------
/source/assets/stylesheets/_html5-reset.css:
--------------------------------------------------------------------------------
1 | /*
2 | html5doctor.com Reset Stylesheet
3 | v1.6.1
4 | Last Updated: 2010-09-17
5 | Author: Richard Clark - http://richclarkdesign.com
6 | Twitter: @rich_clark
7 | */
8 |
9 | html, body, div, span, object, iframe,
10 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
11 | abbr, address, cite, code,
12 | del, dfn, em, img, ins, kbd, q, samp,
13 | small, strong, sub, sup, var,
14 | b, i,
15 | dl, dt, dd, ol, ul, li,
16 | fieldset, form, label, legend,
17 | table, caption, tbody, tfoot, thead, tr, th, td,
18 | article, aside, canvas, details, figcaption, figure,
19 | footer, header, hgroup, menu, nav, section, summary,
20 | time, mark, audio, video {
21 | margin:0;
22 | padding:0;
23 | border:0;
24 | outline:0;
25 | // font-size:100%;
26 | vertical-align:baseline;
27 | background:transparent;
28 | }
29 |
30 | body {
31 | line-height:1;
32 | }
33 |
34 | article,aside,details,figcaption,figure,
35 | footer,header,hgroup,menu,nav,section {
36 | display:block;
37 | }
38 |
39 | nav ul {
40 | list-style:none;
41 | }
42 |
43 | blockquote, q {
44 | quotes:none;
45 | }
46 |
47 | blockquote:before, blockquote:after,
48 | q:before, q:after {
49 | content:'';
50 | content:none;
51 | }
52 |
53 | a {
54 | margin:0;
55 | padding:0;
56 | font-size:100%;
57 | vertical-align:baseline;
58 | background:transparent;
59 | }
60 |
61 | /* change colours to suit your needs */
62 | ins {
63 | background-color:#ff9;
64 | color:#000;
65 | text-decoration:none;
66 | }
67 |
68 | /* change colours to suit your needs */
69 | mark {
70 | background-color:#ff9;
71 | color:#000;
72 | font-style:italic;
73 | font-weight:bold;
74 | }
75 |
76 | del {
77 | text-decoration: line-through;
78 | }
79 |
80 | abbr[title], dfn[title] {
81 | border-bottom:1px dotted;
82 | cursor:help;
83 | }
84 |
85 | table {
86 | border-collapse:collapse;
87 | border-spacing:0;
88 | }
89 |
90 | /* change border colour to suit your needs */
91 | hr {
92 | display:block;
93 | height:1px;
94 | border:0;
95 | border-top:1px solid #cccccc;
96 | margin:1em 0;
97 | padding:0;
98 | }
99 |
100 | input, select {
101 | vertical-align:middle;
102 | }
103 |
--------------------------------------------------------------------------------
/source/assets/stylesheets/_print.scss:
--------------------------------------------------------------------------------
1 | @media print {
2 | nav, .menu {
3 | display: none !important;
4 | }
5 | @page {
6 | margin: 4em;
7 | }
8 | body {
9 | font-size: 1em;
10 | }
11 | body > div {
12 | display: block;
13 | margin: 0;
14 | max-width: 100%;
15 | padding: 0;
16 | }
17 | article {
18 | max-width: 100%;
19 | }
20 | h1 {
21 | /* page-break-before: always; */
22 | }
23 | h1, h2, h3, h4 {
24 | page-break-after: avoid;
25 | }
26 | article {
27 | page-break-before: always;
28 | }
29 | pre {
30 | page-break-inside: avoid;
31 | }
32 | ul, ol {
33 | page-break-inside: avoid;
34 | }
35 | body > div {
36 | padding: 0;
37 | }
38 | body, a {
39 | color: #000;
40 | }
41 | a {
42 | word-wrap: break-word;
43 | }
44 | a[href^="http://"]:after, a[href^="https://"]:after {
45 | content: " (" attr(href) ")";
46 | font-size: 90%;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/source/assets/stylesheets/_response.scss:
--------------------------------------------------------------------------------
1 | $tablet-1: 700px;
2 | $tablet-2: 900px;
3 | $tablet-3: 1024px;
4 | $desktop: 1200px;
5 |
6 | $font-s: 0.875rem; // 14px
7 | $font-m: 1rem; // 16px
8 | $font-l: 1.125rem; // 18px
9 |
10 | html {
11 | font-size: $font-s;
12 | @media screen and (min-width: $tablet-2) { font-size: $font-s; }
13 | @media screen and (min-width: $tablet-3) { font-size: $font-m; }
14 | @media screen and (min-width: $desktop) { font-size: $font-l; }
15 | }
16 |
17 | @media screen and (max-width: $tablet-2) {
18 | body > .page-nav { display: none; }
19 | article > .page-nav { display: block; }
20 | body > div { padding: 3rem 3rem 6.250rem 3rem; }
21 | .menu { display: block; }
22 | .toc { display: none; }
23 | }
24 |
25 | @media screen and (min-width: $tablet-2) {
26 | article > .page-nav { display: none; }
27 | .menu { display: none; }
28 | }
29 |
--------------------------------------------------------------------------------
/source/assets/stylesheets/monstas.scss:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | $light-gray: #F2F2F2;
4 | $red: #ee4444;
5 |
6 | @import "fonts";
7 | @import "html5-reset";
8 | @import "syntax";
9 | @import "layout";
10 | @import "style";
11 | @import "response";
12 | @import "print";
13 |
--------------------------------------------------------------------------------
/source/assets/stylesheets/syntax.css.erb:
--------------------------------------------------------------------------------
1 | <%# A good day theme, though not that colorful %>
2 | <%= Rouge::Themes::Github.render(:scope => '.highlight') %>
3 |
4 | <%# A good day theme, and is very colorful %>
5 | <%#= Rouge::Themes::Base16.render(:scope => '.highlight') %>
6 |
7 | <%# That good sublime text night theme%>
8 | <%#= Rouge::Themes::Base16::Monokai.render(:scope => '.highlight') %>
9 |
--------------------------------------------------------------------------------
/source/index.md:
--------------------------------------------------------------------------------
1 | # Ruby For Beginners
2 |
3 | *[Ruby Monday Study Group](http://rubymonstas.org) curriculum for beginners*
4 |
5 | This book has been written after we have run 4 beginners groups at our [Ruby
6 | Monstas](http://rubymonstas.org) groups in Berlin, and it outlines the current
7 | state of our beginner groups curriculum.
8 |
9 | After completing this curriculum you'll be able to read, understand, and write
10 | basic Ruby code yourself:
11 |
12 | You can use this knowledge to create small tools that might help you in your
13 | day-to-day work (such as converting numbers, or extracting data from files)
14 | that normally would cost a lot of manual work. You'll be able to jump into
15 | other tutorials, and have a much easier time understanding what they're
16 | talking about. And you can start working on our next curriculum which will
17 | walk you through the basics of building an actual
18 | [web application](http://webapps-for-beginners.rubymonstas.org).
19 |
20 | If you'd like to print this book, or export it as a PDF try using [this page](/print.html),
21 | which is a single-page version of the entire book.
22 |
23 | You can find the [source code of this book here](https://github.com/rubymonsters/ruby-for-beginners).
24 |
--------------------------------------------------------------------------------
/source/layouts/layout.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | <%= discover_page_title %>
14 |
15 | <%= stylesheet_link_tag "/assets/stylesheets/monstas" %>
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |