{"id":20689313,"url":"https://github.com/csalmeida/ruby-fundamentals","last_synced_at":"2026-03-14T13:34:35.261Z","repository":{"id":45326142,"uuid":"206360250","full_name":"csalmeida/ruby-fundamentals","owner":"csalmeida","description":"Learning the Ruby programming language.","archived":false,"fork":false,"pushed_at":"2021-12-25T20:54:09.000Z","size":204,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T16:34:29.940Z","etag":null,"topics":["ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csalmeida.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-04T16:08:12.000Z","updated_at":"2023-07-31T07:30:53.000Z","dependencies_parsed_at":"2022-09-09T06:21:26.709Z","dependency_job_id":null,"html_url":"https://github.com/csalmeida/ruby-fundamentals","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csalmeida%2Fruby-fundamentals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csalmeida%2Fruby-fundamentals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csalmeida%2Fruby-fundamentals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csalmeida%2Fruby-fundamentals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csalmeida","download_url":"https://codeload.github.com/csalmeida/ruby-fundamentals/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250271498,"owners_count":21403201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ruby"],"created_at":"2024-11-16T23:09:11.423Z","updated_at":"2026-03-14T13:34:35.215Z","avatar_url":"https://github.com/csalmeida.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ruby Fundamentals\n\nIntroduction to core features of the [Ruby](https://www.ruby-lang.org) programming language and initial experiments.\n**Official Documentation:** https://ruby-doc.org/\n\n## Table of Contents\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand contents\u003c/summary\u003e\n\n- [Getting Started](#getting-started)\n  - [The Interactive Ruby Shell](#the-interactive-ruby-shell)\n  - [Accessing Documentation](#accessing-documentation)\n  - [Challenges](#challenges)\n- [Object Types](#object-types)\n  - [Objects](#objects)\n  - [Variables](#variables)\n  - [Numbers](#numbers)\n  - [Strings](#strings)\n  - [Arrays](#arrays)\n  - [Hashes](#hashes)\n  - [Symbols](#symbols)\n  - [Booleans](#booleans)\n  - [Ranges](#ranges)\n  - [Constants](#constants)\n  - [Nil](#nil)\n  - [Challenge: Roman Numerals](challenges/roman-numerals.rb)\n- [Control Structures](#control-structures)\n  - [Conditionals](#conditionals)\n  - [Loops](#loops)\n  - [Iterators](#iterators)\n  - [Challenge: Blank Patterns](challenges/blank-patterns.rb)\n- [Scripting](#scripting)\n  - [Best Practices](#best-practices)\n  - [Exit a running script](#exit-a-running-script)\n  - [Input and output](#input-and-output)\n  - [Challenge: Guessing Game](challenges/guessing-game.rb)\n- [Enumerables and Code Blocks](#enumerables-and-code-blocks)\n  - [Enumerables](#enumerables)\n  - [What is a code block?](#what-is-a-code-block)\n  - [Find Methods](#find-methods)\n  - [Map Methods](#map-methods)\n  - [Inject Methods](#inject-methods)\n  - [Sort Methods](#sort-methods)\n  - [Merge Methods](#merge-methods)\n- [Custom Methods](#custom-methods)\n  - [Define and Call Methods](#define-and-call-methods)\n  - [Variable Scope](#variable-scope)\n  - [Arguments](#arguments)\n  - [Return](#return)\n- [Further Resources](#further-resources)\n\u003c/details\u003e\n\n# Getting Started\n\nTo get started Ruby needs to be installed on the machine:\n```\nruby -v \n```\n\nShould return something similar to:\n`ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]`\n\n\u003e If the `ruby` command is not found, [install Ruby](https://www.ruby-lang.org/en/documentation/installation/).\n\nTo run an instruction on the command line:\n```\nruby -e 'puts \"Hello, World\"'\n```\n\nThis will print `Hello, World` to the terminal.\n\nRuby can also be ran from files, start by creating one:\n```\ncd learning-ruby\ntouch hello.rb\n```\n\nAdd an instruction to the file:\n``` ruby\n# object-types/hello.rb\nputs \"Hello World\"\n```\n\nRun the file in the terminal:\n```\nruby hello.rb\n```\n\nAgain, `Hello, World` will print to the terminal.\n\n\n## The Interactive Ruby Shell\n\nWhilst learning or experimenting with features, it is useful to run commands. This can be done using the Interactive Ruby Shell (IRB):\n\n```\nirb\nirb(main)::001:0\u003e 1 + 1\n=\u003e 2\nirb(main)::002:0\u003e puts 2077\n2077\n=\u003e nil\n```\n\nIn the console above, `irb` was ran. Subsequently, an addition operation was made where the result was returned. \n\nThe next command prints `2077` into the terminal but `nil` is also printed. This is because in Ruby most instructions return a value and `irb` makes that aspect visible.\n\n## Accessing Documentation\n\nAdditionally, it might be helpful to access [Ruby's official documentation](https://ruby-doc.org/) to learn more about its capabilities. This document provides details about objects, their methods and more.\n\nAlternatively, documentation is shipped with each Ruby installation, and can be accessed from the terminal using `ri` (Ruby Information):\n\nStart by looking up a class:\n```\nri String\n```\n\u003e Press `space` for next page (shows available methods) or `q` to quit.\n\nOnce a method is known it can be accessed directly by using the following:\n\n```\nri String#uppercase\n```\nUsing `ri` allows documentation to be accessed offline if needed.\n\n## Challenges\nThere are a few challenges that were completed to solidify knowledge for each chapter. Consult [`/challenges`](challenges/) to access them, both include a file with the challenge and another with a `solution.rb`.\n\n\u003e Challenges were designed by [Kevin Skoglund](https://twitter.com/kskoglund) for the [Ruby Essential Training: 1 The Basics](https://www.linkedin.com/learning/ruby-essential-training-1-the-basics/) (linkedin.com)\n\n# Object Types\nAn introduction to the various object types (also referred as data types) available in Ruby and how they work.\n\n## Objects\n\nTo learn Ruby, it is helpful to start by understanding objects as the language is an extreme object-oriented programming language.\n\nIn other languages that's not always the case, many other object-oriented languages make use of something called _\"primitives\"_ which make up the most basic parts of the language and they might not necessarily relate with each other.\n\nHowever in Ruby, _almost_ everything is an object and these can be interacted in similar ways. They are called objects because they are rather analogous to objects in the real world.\n\nFor instance a `book` is an object with certain properties, uses or behaviours. A book can have a blue cover, 250 pages, and a language it is published in.\n\nThe `book` can be opened, read and closed.\n\nThere are other books with different properties but all books are similar to each other in the sense they have a cover, a title, an author, pages and so on.\n\nObjects work in a similar way, they act as a boilerplate with the option to instantiate many copies, each with their own properties.\n\n## Variables\n\nAs mentioned in the [objects chapter](#objects), _almost_ everything is an object in Ruby. One of the exceptions are variables which act as references to objects.\n\nThey keep track of objects whilst programming and can be treated as objects once an object is assigned to them.\n\nIn the example below, `x`, `y` and `z` are all variables. They're not objects but they reference them (yes, `integers` are objects too) and they can reference each other.\n\n``` ruby\n# object-types/variables.rb\nx = 1\ny = x + 2\nz = y - x\n```\n\nThe variables names used for the example above are simple and are valid in Ruby. However, Ruby has it's own convention for naming variables by separating words with an `_`, in plain English:\n\n``` ruby\n# object-types/variables.rb\nfirst_name = \"Cristiano\"\nenjoying_ruby = true\narticles_written = 100\n```\n\nVariables not only allow values to be assigned to them but also to be retrieved:\n\n``` ruby\n# object-types/variables.rb\nx = 2077\nputs x\n```\n\n#### Variable Scope Indicators\n\nThere are some variables with special meaning. These have characters prexifes to specify what they are:\n\n|    Type   |    Declaration    |\n| ------------- |:-------------:|\n| **Global**     | $variable |\n| **Class**      | @@variable |\n| **Instance**   | @variable |\n| **Local** | variable |\n| **Block** | variable |\n\nMost of the time, local variables are used but other types will be expanded upon on later chapters. \n\n## Numbers\nIn Ruby, numbers are split into two categories of objects, `integers` for whole numbers and `floats` for decimals, when more precision is required.\n\nMath operations can be performed:\n``` ruby \n# object-types/numbers.rb\nputs \"Addition (4+2):\"\nputs 4 + 2\n\nputs \"Subtraction (4-2):\"\nputs 4 - 2\n\nputs \"Division (4/2):\"\nputs 4 / 2\n\nputs \"Multiplication (4*2):\"\nputs 4 * 2\n\n# 4 raised to the power of 2.\nputs \"Exponential (4**2):\"\nputs 4 ** 2\n\n# Remainer of dividing 4 by 2.\nputs \"Modulus (4%2):\"\nputs 4 % 2\n```\n\nNumbers can be assigned to variables like any other object and math assigned operators can be used as well. This allows a number to be added, subtracted, divided or multiplied to the value a variable currently points to:\n\n``` ruby\n# object-types/numbers.rb\n\n# Assigning a number to x.\nx = 4\n\n# Adding 2 to 4.\nx += 2 # same as: x = x + 2\n\n# Subtracting 2 from 6.\nx -= 2\n\n# Dividing 4 by 2.\nx /= 2\n\n# Multiplying 2 by 2.\nx *= 2\n\n# 4 to the power of 2.\nx **= 2\n\n# The remainder of diving 16 by 2.\nx %= 2\n```\n\nIntegers and Floats have multiple methods that can be applied to them, for instance:\n\n``` ruby\n100.next # 101\n2.6.round # 3\n```\n\nConsult `ri` or the documentation for more methods on `Floats` and `Integer` objects.\n\n##### Notes on Floats\n\nFloats are similar to Integers but with a few differences, specifically the way Ruby treats them in operations.\n\nWhen adding two `Integer`s, the same type will be returned:\n``` ruby\n2 + 2 # 4, Integer\n```\n\nSimilarly, the same happens with `Float`s:\n``` ruby\n2.6 + 2.6 # 5.2, Float \n```\n\nHowever, if a `Float` is present in an operation with an `Integer` the type will convert, as Ruby assumes precision is required:\n\n``` ruby\n5 + 2.6 # 7.6, Float\n```\n\nThis rule can lead to confusion in operations that use division. As two integers were provided in the example below, Ruby kept its type the same:\n``` ruby\n10 / 3 # 3, Integer\n```\n\nTo evaluate this expression to a more precise value (closer to being correct), both at least one of them would require to be a `Float`:\n\n``` ruby\n10.0 / 3 # 3.3333333333333335, Float\n# OR\n10 / 3.0\n```\n\n## Strings\n\nStrings are a common feature in most programming languages, they represent a sequence of characters and are used to put together pieces of text.\n\nA string is represented by wrapping it in single or double quotes. There are differences between the two which might help decide when to choose one over the other.\n\n``` ruby\n\"Hello, world\"\n'Hello, world'\n```\n\n### Concatenation\n\nOne common operation that is performed on `String`s is concatenation. It combines one or more `String`s into a single one by adding them together.\n\nIn the example below the words _hello_ and _world_ are contatenated. Notice how the comma and the space is also concatenated in the middle to show it correctly, otherwise it would output _helloworld_ with no spacing:\n\n``` ruby\n\"Hello\" + \", \" + \"world\" # Hello, world\n```\n\nStrings can also be assigned to variables like any other object:\n\n``` ruby\n# object-types/strings.rb\ngreeting = \"Hello\"\ntarget = \"world\"\nsentence = greeting + \", \" + target\nputs sentence # Hello, world\n```\n\nAnother way to join strings together is by using the `append` operator. It looks like the _less than, less than_ sign and suggests that one string is being shoved into the other:\n\n``` ruby\n# object-types/string.rb\ngreeting = \"Hello\"\ngreeting \u003c\u003c \", \"\ngreeting \u003c\u003c \"nature\"\nputs greeting # Hello, nature\n```\n\nStrings also can be repeated by using the multiplication operator  (`*`):\n\n``` ruby\n# object-types/strings.rb\n\"ruby \" * 4 # ruby ruby ruby ruby (Ohhuuohhhuhhohhh)\n```\n\nThere are many methods that can be used with strings, consult `ri` to find out which ones.\n\n``` ruby\n# object-types/strings.rb\nputs \"ruby\".capitalize # Ruby\nputs \"ruby\".upcase.reverse # YBUR\n```\n\n### Escaping and Interpolation\n\nBesides the aspects mentioned above there are some details worth being aware of when working with strings, starting with string escaping.\n\nIn the example below, there is a first string delimited by double quotes with _Let's escape_ inside. There is a single quote in this string (in the word _let's_) and it is valid Ruby.\n\nThe second string is wrapped with single quotes but it introduces a problem. As Ruby established single quotes to be the delimiter of this string, it will mark its end when it finds its pair. So the string ends up being _Let_ instead of the intended _Let's escape_.\n\n``` ruby\n\"Let's escape!\"\n'Let's escape!'\n```\n\nThe same issue would occur with double quotes:\n\n``` ruby \n'They said \"hi\" back'\n\"They said \"hi\" back\"\n```\n\nTo keep this issue from happening characters can be escaped. This means that `\"` or `'` can be used inside a string even in these cases, making it valid Ruby:\n\n``` ruby \n# object-types/strings.rb\n'Let\\'s escape!' # Let's escape!\n\"They said \\\"hi\\\" back\" # They said \"hi\" back\n```\n\nThe `\\` escape character can also be used as special control characters such as a tab and a new line. These only work on `\"` strings as `'` will print the backslash as well, one of the differences between the two.\n\n``` ruby\n\"\\tLet\\'s escape!\\n Go!\" #    Let's escape!\n                         # Go!\n```\n\nAdditionally, interpolation can be used on strings. This means that something else can be inserted into the string. This something else is an expression, a question that Ruby will try to answer.\n\nAn expression could be a number, a mathematical operation, running a method on an object, other objects or most commonly, a variable.\n\nSame as the example above, interpolation only works on `\"` strings:\n\n``` ruby\n# object-types/strings.rb\ngreeting = \"Hello\"\ntarget = \"world\"\nsentence = \"#{greeting}, #{target}\"\nputs sentence # hello, world\n```\n\nMethods and math operations can be ran inside the interpolation brackets:\n\n``` ruby\nsentence = \"#{greeting}, #{target.upcase}\" # hello, WORLD\nputs \"2 + 2 = #{2 + 2}\" # 2 + 2 = 4 \n```\n\n## Arrays\n\nRuby also supports arrays, an ordered, integer-indexed collection of objects.\n\nObjects are put into an ordered list and can be referred to by the position that they hold when using arrays.\n\nThe position count starts at `0` (0 indexed), common on most programming languages. This means that the first item of an array is accessed by refering `0` as its index, not `1`.\n\nIn the example below an empty array is declared. A second one is also declared with both strings and an integer inside:\n\n``` ruby\n# object-types/arrays.rb\nempty_array = []\nan_array = ['a', 'b', 'V', 2077]\n```\n\nTo access these values the position must be referenced, positions that don't have a value return `nil`:\n\n``` ruby\n# object-types/arrays.rb\nan_array[0] # a\nan_array[3] # 2077\nan_array[4] # nil\n```\n\nValues can also be assigned to array positions, position `0` will no longer point at the value `'a'` and will point at `\"Bug\"` instead:\n\n``` ruby\n# object-types/arrays.rb\nan_array[0] = \"Bug\"\n```\n\nA new item can be added at the end of the array by using the `append` operator:\n\n``` ruby\n# object-types/arrays.rb\nan_array \u003c\u003c \"Dex\"\nputs an_array[4] # Dex\n```\n\nArrays can nest other arrays and can be accessed starting from the end of the array by using negative values:\n\n``` ruby\n# object-types/arrays.rb\na_second_array = [\"Omboa\", \"Kalunga\", \"Kimbo\", [\"Ocuria\", \"Onjo\"]]\n\nruby_array = [\"g\",\"o\",\"r\",\"u\",\"b\",\"y\"]\nruby_array[2] # \"r\"\nruby_array[-1] # \"y\"\n```\n\nAdditionally, two positions or a [range](#ranges) can be passed to return only a set of values.\n\n``` ruby\n# object-types/arrays.rb\nruby_array[2,4] # [\"r\",\"u\",\"b\",\"y\"]\nruby_array[-2,2] # [\"b\",\"y\"]\nruby_array[2..3] # [\"r\",\"u\"]\nruby_array[-4..-1] # [\"r\",\"u\",\"b\",\"y\"]\n```\n\n### Array Methods\n\nArrays are used very frequently in Ruby programs and there are useful methods that can be applied to make it easier to work with them.\n\n```ruby\n# object-types/arrays.rb\nmixed_array = [2,4,['a', 'b'], nil, 4, 'c']\nmixed_array.length # 6\nmixed_array.size # 6\nmixed_array.reverse # [\"c\", 4, nil, [\"a\", \"b\"], 4, 2]\nmixed_array.shuffle # [[\"a\", \"b\"], 4, nil, 2, 4, \"c\"]\n```\n\nThe methods above return a new value but don't affect the array stored in `mixed_array`. To make the change permanent a `!` can be added at the end of the method declaration:\n\n``` ruby\n# object-types/arrays.rb\nmixed_array.uniq! # [2, 4, [\"a\", \"b\"], nil, \"c\"]\nmixed_array.compact! # [2, 4, [\"a\", \"b\"], \"c\"]\nmixed_array.flatten! # [2, 4, \"a\", \"b\", \"c\"]\n```\n\nThe '?' is another Ruby idiom that can be also used in methods to query or find out about and in most cases it returns a [`boolean`](#booleans) value:\n\n``` ruby\n# object-types/arrays.rb\nmixed_array.include?(2) # true\n```\n\nThere are other common methods that are used to manipulate arrays. Some methods take parameters in order to return a new array or another output:\n\n```ruby\nmixed_array\nmixed_array.delete_at(1) # [2, \"a\", \"b\", \"c\"]\nmixed_array.delete('c') # [2, \"a\", \"b\"]\n\n[1,2,3,4,5].join(',') # \"1,2,3,4,5\"\n\"1,2,3,4,5\".split(',') # [1,2,3,4,5]\n```\n\nPlease refer to `ri` for more information on arrays.\n\n## Hashes\n\nHashes are a collection just like an array. However, they are _unordered_ and object-indexed (or key-value pairs).\n\nThis object type is useful when the order of a list does not matter so much and the convenience of accessing items by a label is required. Each label (`key`) needs to be unique.\n\nHashes are also known as dictionaries or associative arrays in other programming languages.\n\nAn example of declaring a hash, how to access the value and reset a value:\n\n``` ruby\n# object-types/hashes.rb\ncar = {\n  'brand' =\u003e 'Tesla',\n  'model' =\u003e 'X',\n  'color' =\u003e 'blue',\n  'interior_color' =\u003e 'tan',\n  'extras' =\u003e true\n}\n\nputs car['model']\n\ncar['color'] = \"red\"\ncar['doors'] = 2\n```\n\nHashes have also useful methods that can be used to manipulate them. Refer to `ri` for details:\n\n``` ruby\n# object-types/hashes.rb\nputs car.keys # Shows available keys of a hash.\nputs car.values # Shows all values in a hash.\nputs car.to_a # Turns a hash into an array.\n```\n\n## Symbols\n\nOne of the most misunderstood objects in Ruby as most languages don't have a similar one. A symbol is like a string that acts as a label.\n\nSymbols are like strings but cannot be edited, they begin with a colon and are not delimited by quotes. \n\nThe name of the symbol follows the same conventions as variables, all lowercase and separated by underscores. For instance, `:first_name`.\n\nA symbol can be used to define keys in hashes. This can bring two benefits: First that symbols are not editable, therefore keys cannot be changed somehow (their values can) and secondly, using symbols allows Ruby to use memory more effectively:\n\n```ruby\n# object-types/symbols.rb\nperson = {\n  :first_name =\u003e \"Richard\",\n  :last_name =\u003e \"Bona\"\n}\n\nperson[:last_name]\n```\n\nSymbols can also be written in a shorthand form. They're still symbols even if the colon is at the end to separate the key from the value:\n\n```ruby\n# object-types/symbols.rb\nanother_person = {\n  first_name: \"Esperanza\",\n  last_name: \"Spalding\"\n}\n\nanother_person[:last_name]\n```\n\n## Booleans\n\nAn object that is either `true` or `false`. Its mostly used for comparisons and logical expressions that define whether a piece of code should run.\n\nBooleans can either be defined with the keywords `true` or `false`. The values `1` or `0` may not be used in boolean expressions as they won't evaluate to the expected value. For instance, **both** `0 == true` and `1 == true` will evaluate to `false`.\n\n```ruby\n# object-types/booleans.rb\nx = true\ny = false\n```\n\nTo define conditions, comparison and logic operators are used:\n\n|       |        |\n| ------------- |:-------------:|\n| Equal    | **==** |\n| Less than | **\u003c** |\n| Greater than | **\u003e** |\n| Less than or equal to | **\u003c=** |\n| Greater than or equal to | **\u003e=** |\n| Not | **!** |\n| Not equal | **!=** |\n| And | **\u0026\u0026** |\n| Or | **||** |\n\nMost of the time, booleans will be received as return values from a condition:\n\n```ruby\n# object-types/booleans.rb\nz = 20\n\nz == 77           # false\nz \u003c 77            # true\nz \u003e 77            # false\nz \u003e= 77           # true\nz \u003e= 77           # false\n!z                # false\nz != 77           # true\nz \u003c 77 \u0026\u0026 z \u003e 3   # true\nz \u003c 77 || z \u003e 10  # true\n```\n\nAdditionally, booleans can be returned from methods that use the `?` sign:\n\n```ruby\n# object-types/booleans.rb\nz = 20\nw = []\n\nz.nil? \nz.between?(1, 5)\nw.empty?\n```\n\n## Ranges\n\nA range of sequential objects. Most of the time these will be numbers but they don't have to.\n\nRanges can be inclusive or exclusive, but most of the time inclusive ones tend to be used:\n\n```ruby\ninclusive = 1..10 # 1 to 10\nexclusive = 1...10 # 1 to 9\n```\n\n```ruby\ninclusive.begin # 1\ninclusive.first # 1\ninclusive.end # 10\nexclusive.first # 1\nexclusive.end # 10 (surprising right?)\n```\n\nRanges can be exploded to create arrays:\n\n```ruby\nnumbers = [*inclusive] # [1,2,3,4,5,6,7,8,9,10]\n```\n\nRanges are typically numbers but they don't have to be. Any objects with a sequential order can be put into a range:\n\n```ruby\nalphabet = 'a'..'z' # A range with the letters a to z.\nalphabet.include?('c') # true\nletters = [*alphabet] # [a, z]\n```\n\n## Constants\n\nConstants are akin to variables with the difference being that once defined, it is not expected for that value to ever change during runtime.\n\nConstants are defined using all uppercase letters.\n\n```ruby\n# object-types/constants.rb\nDATE_OF_BIRTH = \"March 21, 1940\"\n```\n\nUsually, constants will throw an error in most programming languages it there's an attempt of changing them. However, Ruby will let the constant change and issue a warning instead.\n\n## Nil\n\nNil is an object that equates to nothing. Some languages might call it `null`. For instance `nil` will be returned when a variable is empty.\n\n```ruby\n# object-types/nil.rb\nmoney_in_the_bank = nil\n\nputs money_in_the_bank.class # NilClass\n```\n\nIn some languages `nil` can equate to `false` but this is not the case in Ruby. In the cases where a boolean value must be returned it is best to define a conditional statement instead asking if the value is `nil`:\n\n```ruby\n# object-types/nil.rb\nmoney_in_the_bank.nil? # true\n\nmoney_in_the_bank == nil # true\n\n!money_in_the_bank # true\n```\n\nAll the above statements will return true if the variable `money_in_the_bank` is empty.\n\n\u003e There's a challenge available for this chapter: [Roman Numerals](challenges/roman-numerals.rb)\n\n# Control Structures\n\nThey add dynamism to the code being written and allow to determine the circumstances when code executes. For instance, using conditionals helps to define a code block to only run when a condition is met. Loops can run a code block a specific number of times or until a condition is met. Furthermore, there are iterators which uses a set of objects and it will loop moving through an `array` or a `hash`.\n\nControl structures require multiple lines of code to be defined so it is recommended that these are written in a file rather than `irb` as they have to be retyped on mistakes.\n\n## Conditionals\n\nConditionals define when a code block runs and they are declared with the `if`, `else` and `elsif` keywords. The condition it takes must return a `boolean` value, evaluating to either `true` or `false`.\n\n```ruby\nif boolean\n # execure this code\nend\n```\n\nThe code between the `if` condition and the `end` keyword forms a block that will only execute if that condition is met.\n\n```ruby\n# control-structures/conditionals.rb\nif fruit == 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nend\n```\n\nAn `else` keyword may be introduced if something else should run when the condition is not met:\n\n```ruby\n# control-structures/conditionals.rb\nif fruit == 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nelse\n  puts \"Oh! I guess there are no Mangoes left.\"\nend\n```\n\nConditionals can also accommodate more than one comparison. If the previous one is not met, it will keep working down the block until one `elsif` is met or when the `else` block is hit.\n\n```ruby\n# control-structures/conditionals.rb\nif fruit == 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nelsif fruit == 'pineapple'\n  puts \"Pineapples are nice too, though a bit controversial on pizza.\"\nelse\n  puts \"Oh! I guess there's no fruit left.\"\nend\n```\n\n### Unless\nThe `unless` keyword is the opposite of `if` and it effectively means _\"if not\"_. It can be used to add readability to a block:\n\n```ruby\n# control-structures/conditionals.rb\nunless fruit == 'mango'\n  puts \"This fruit is not a mango.\"\nend\n```\n\n### Case\nThe if/else statement structure makes sense when a couple of conditionals are being checked. However, once there are a number of them a `case` statement can be considered.\n\n```ruby\ncase\nwhen boolean\n  # code\nwhen boolean\n  # another piece of code\nwhen boolean\n  # yet another block of code\nelse\n  # if no condition is met, run this line\nend\n```\n\nUsing cases makes writing blocks with multiple conditions clearer:\n\n```ruby\n# control-structures/conditionals.rb\ncase\nwhen fruit == 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nwhen fruit.length \u003e 5\n  puts \"The name of this fruit is long.\"\nwhen fruit = 'pineapple'\n  puts \"Pineapples are nice too, though a bit controversial on pizza.\"\nelse\n  puts \"Oh! I guess there's no fruit left.\"\nend\n```\n\nCases can also be implemented on a slightly different format where a test value is put in place and will be compared with the values provided for each block, if it matches it will run the statements inside it. This implementation is more akin to a `switch` statement present in most programming languages;\n\n```ruby\n# control-structures/conditionals.rb\ncase fruit\nwhen 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nwhen 1\n  puts \"Fruit cannot be a number.\"\nwhen 'pineapple'\n  puts \"Pineapples are nice too, though a bit controversial on pizza.\"\nelse\n  puts \"Oh! I guess there's no fruit left.\"\nend\n```\n\nNow the variable being compared is added as a `case` and Ruby will work down each value until one matches or hits the `else` statement.\n\n### Shorthand for conditionals\n\nThere are shorthand for writing conditionals that can be applied when the logic is simple, for instance a _ternary operator_:\n\n```ruby\n# control-structures/conditionals.rb\nputs fruit == 'mango' ? \"A #{fruit.upcase}! They're so tasty!\" : \"Oh! I guess there are no Mangoes left.\"\n```\n\nOn the regular if/else syntax the same logic would look like this:\n\n```ruby\n# control-structures/conditionals.rb\nif fruit == 'mango'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nelse\n  puts \"Oh! I guess there are no Mangoes left.\"\nend\n```\n\nThere is also the _or operator_, defined by the pipe sign `||` and it is useful when setting default values or evaluating based on two or more conditions concurrently:\n\n```ruby\n# control-structures/conditionals.rb\nfavorite_fruit = fruit || 'apple' # pineapple\n```\n\nThe example above reads \"if `fruit` doesn't have a value or evaluates to `false` assign `'apple'` as the favorite fruit.\n\nThe _OR_ operator can also be used in conditional blocks in case one of the requirements applies it will execute it:\n\n```ruby\n# control-structures/conditionals.rb\nif fruit == 'mango' || fruit == 'pineapple'\n  puts \"A #{fruit.upcase}! They're so tasty!\"\nelse\n  puts \"Oh! I guess there are no Mangoes or Pineapples left.\"\nend\n```\n\nThe OR operator can also set default values if no value exists:\n\n```ruby\n# control-structures/conditionals.rb\nfavorite_fruit ||= 'passion fruit'\n# OR\nfavorite_fruit = 'passion fruit' unless favorite_fruit\n```\n\nIn this case the statement is different, it is declared that if `favourite_fruit` has no value then set it to `'passion fruit'`, otherwise keep it as it is. It is the same as:\n\n```ruby\nunless favorite_fruit\n  favorite_fruit = 'passion fruit'\nend\n```\n\nLastly, conditionals can be used as _statement modifiers_. These are usually used sparingly as a complete `if` statement tends to be more readable. Statement modifiers are declared in a single line.\n\n```ruby\n# control-structures/conditionals.rb\nputs favorite_fruit if fruit == favourite_fruit\n```\n\n## Loops\n\nUsed to repeat run a block of code multiple times, the simplest loop in Ruby is comprised of the `loop`, `do` and `end` keyword.\n\n```ruby\nloop do\n  # code to repeat here\nend\n```\n\nHowever, this code would repeat forever so a conditional or a way to limit the iterations is necessary to close the loop. There are a few _control methods_ that can be used to achieve this:\n\n|       |        |\n| ------------- |:-------------:|\n| `break`     | Terminates the loop |\n| `next`     | Jump to next iteration |\n| `redo` | Redo an iteration |\n| `retry` | Start the whole loop over |\n\nA loop in Ruby can look similar to the following example:\n\n\u003e An `index` and a condition is used to keep track of how many iterations are left to do.\n\n```ruby\n# control-structures/loops.rb\nindex = 5\nloop do\n  break if index \u003c= 0\n  puts \"Countdown: #{index}\"\n  index -= 1\nend\nputs \"Blast off!\"\n```\n\nHowever, defining loops this way in Ruby is not so common as there are streamlined ways of achieving the same results:\n\n```ruby\nwhile boolean\n  # run code\nend\n\nuntil boolean\n  # run code\nend\n```\n\nA more common way of defining loops is using `while` or `until`. The former iterates while a condition is met, whilst the latter will iterate until a condition is met.\n\nThe `break` and `do` keywords are implicit and can be ommited:\n\n```ruby\n# control-structures/loops.rb\nindex = 5\nwhile index \u003e= 0\n  puts \"Countdown: #{index}\"\n  index -= 1\nend \nputs \"Blast off!\"\n\nindex = 5\nuntil index \u003c= 0\n  puts \"Countdown: #{index}\"\n  index -= 1\nend \nputs \"Blast off!\"\n```\n\nThis is how to work with loops in Ruby.\n\n## Iterators\n\nLoops in Ruby are fairly primitive when compared to `iterators`. They have robust support in the language and are used far more often than loops.\n\nTo iterate means to say or do again. In the case of programming it means to apply a procedure repeatedly. \n\nAn `iterator` is going to perform code on each item in a set. Most of the time could be an `array` or a `hash` but it could also be a `range`.\n\nAn introductory iterator is the `times` iterator:\n\n```ruby\n# control-structures/iterators.rb\nindex = 5\nindex.times do\n  puts \"Countdown: #{index}\"\n  index -= 1\nend\nputs \"Blast off!\"\n```\n\nThere are other types of iterators, in the examples below these are wrapped in curly braces (`{}`) since they're on a single line. However, the word `do` and `end` can be used instead to wrap them in a code block:\n\n|       |        |\n| ------------- |:-------------:|\n| **times**     | `5.times { puts \"Hello\" }` |\n| **upto**     | `1.upto(5) { puts \"Hello\" }` |\n| **downto** | `5.downto(1) { puts \"Hello\" }` |\n| **each** | `(1..5).each { puts \"Hello\" }` |\n\nHowever, running iterators on a single line does not allow the initial loop example to be created using them since it makes use of the current iteration number (`index`) to count down.\n\nTo access `index`, a block variable needs to be passed in, allowing to make use of the value as it iterates through:\n\n```ruby\n# control-structures/iterators.rb\n5.downto(1) do |index|\n    puts \"Countdown: #{index}\"\nend\nputs \"Blast off!\"\n```\n\nUsing an `iterator` the `index` does not need to be incremented (or decremented in this case), Ruby does it automatically.\n\n### Iterators by class\n\nThere are a number of iterators that can be applied to a class specifically:\n\n|       |        |\n| ------------- |:-------------:|\n| **numbers**     | `times`, `upto`, `downto`, `step` |\n| **range**     | `each`, `step` |\n| **string** | `each_line`, `each_char`, `each_byte` |\n| **array** | `each`, `each_index`, `each_with_index` |\n| **hash** | `each`, `each_key`, `each_value`, `each_pair` |\n\nPlease [consult the documentation](https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/iterators.html) for more information on how to use class specific iterators.\n\nAn `each` loop can be written with the `for` keyword as well, although most Rubyists tend to prefer the former way of defining them:\n\n```ruby\n# control-structures/iterators.rb\nfruits.each do |index|\n  puts \"I like #{fruits[index]}\"\nend\n\nfor fruits in fruit\n  puts \"#{fruit} are nice\"\nend\n```\n\n\u003e There's a challenge available for this chapter: [Blanket Patterns](challenges/blanket-patterns.rb)\n\n# Scripting\n\nExpanding on Ruby scripting best practices and how to take in user input.\n\n## Best practices\n\nAs a start it is convention that Ruby files are named with the `.rb` extension. This hints the operative system (OS) that the contents of a file are to be parsed using the Ruby interpreter.\n\nAnother best practice is to add a `shebang` at the top of the file. This is a Unix convention which stands for a `#!` and it is used to specify what should be used to run the program.\n\n```ruby\n#!/usr/bin/env ruby\n```\nThe line above assures programs are portable, it checks the user environment (`env`) and figures out which version of Ruby is active (`ruby`)\n\nUnix environments will use it to run the script whilst systems such as Windows will ignore it as it will look like a comment and will make use of file association instead.\n\n## Exit a running script\n\nThere are multiple ways of exiting a script in Ruby. The most common way is to let it end automatically after running all the defined statements in a file.\n\nSometimes programs might have another reason to exit such as by a certain condition being met or by user input.\n\nThere are a few methods available  that exit a script:\n\n|       |        |\n| ------------- |:-------------:|\n| `exit` or `exit!`     | Exits the script |\n| `abort(msg)`     | Exits the script with the possibility of returning a message. |\n| `control+c` | Combination of keys that sends an interrupt signal, exiting the script at any stage. |\n\n```ruby\n# ruby-scripting/exit-script.rb\nlegends.each do |legend|\n  if legend == 'kalunga'\n    exit\n  end\n  puts \"#{legend.capitalize} joined the circle.\"\nend\n```\n\nThe example above shows the `exit` keyword in use. If the condition is met the script will exit before it prints the sentence with its name. \n\nThis is different than `break` for instance, since the script would still run until the end and only the loop would stop running.\n\n## Input and output\n\nExploring how to input and output values in Ruby.\n\n### Output\n\nA command used throughout this document is `puts`, which allows something to be printed in the console.\n\nThere's a variation of `puts` which is `print`, with the difference being that `puts` _always_ adds a line return at the end whilst `print` does not unless specified.\n\n### Input\n\nThere's also the ability to receive user input using `gets`.\nIt will take everything typed until a user hits return.\n\n```ruby\n# ruby-scripting/input-output.rb\nprint \"What is your name? \"\nresponse = gets\n\nputs \"Hello, #{response}!\"\n```\n\nIn the example above, a question is printed and the input is stored in a variable called `response`. Then, it is printed again with a greeting using `puts`.\n\nHowever, the output would not look quite right since `gets` much like `puts`, adds a new line at the end so the last character of the greeting would be in a new line:\n\n```bash\nHello, Omboa\n!\n```\n\nTo address this case, two methods can be used alongside `gets`, namely, `chop` and `chomp`. `chop` removes the last character of a string whilst `chomp` removes the last character only if it's a new line character.\n\n```ruby\n# ruby-scripting/input-output.rb\nprint \"What is your name? \"\nresponse = gets.chomp\n\nputs \"Hello, #{response}!\"\n```\n\nNow the response would look as expected:\n\n```bash\nHello, Omboa!\n```\n\nUsing input and outputs can help when interacting with the user.\n\n\u003e There's a challenge available for this chapter: [Guessing Game](challenges/guessing-game.rb)\n\n# Enumerables and Code Blocks\n\nThis chapter will go more in depth on enumerables, powerful methods that can be used on them and how code blocks work.\n\n## Enumerables\n\nEnumerables are a set of items that can be counted. These include _arrays_, _ranges_ and _hashes_. Strings however, they're not considered an enumerable since it is difficult to determine what is being counted as some characters can be multi byte characters and there was some ambiguity on what should be counted by default (characters or bytes).\n\nStrings will still behave as enumerables if what is being counted is specified.\n\nEnumerables is a module within the Ruby language. A module is essentially a group of methods that can be included in other `class`es. The concept of modules and classes will be [explored at a later chapter](https://github.com/csalmeida/ruby-classes-and-modules) but it essentially means that, for instance, an `Array` can inherit methods from an `Enumerable` and make use of them. Refer to [the documentation in the included modules section](https://ruby-doc.org/core-2.6.4/Array.html) to find if methods from enumerables are available on an object.\n\nThe methods from `Enumerable` will be explored throughout this chapter.\n\n## What is a code block?\n\nCode blocks were first introduced in this document when used with [iterators](#iterators) but it is worth expanding further.\n\nIn the case of using iterators, the code block is defined by the words `do` and `end`, acting as delimiters for the block.\n\n```ruby\n5.times do\n  puts \"Hello\"\nend\n```\n\nThe same code block can be defined in a single line if delimited by curly-braces:\n\n```ruby\n5.times { puts \"Hello\" }\n```\n\nThe convention normally is to use the _curly-brace format_ on either single line blocks or blocks that return data but make no changes to it.\n\nThe _do-end format_ is normally used when more than one line is required or when data is changed and returned.\n\n\u003e \"In short, use the curly-braces when it's simple, use do and end when it's anything more complex – [Kevin Skoglund](https://twitter.com/kskoglund)\n\n### Block Variables\n\nThere are also block variables that assign an item to it, defined by the pipe sign (`|block_variable|`) and the variable can be used inside that code block.\n\n```ruby\n5.downto(1) do |i|\n  puts \"Countdown: #{i}\"\nend\n\n# Or in a single line:\n\n5.downto(1) { |i| puts \"Countdown: #{i}\" }\n```\n\nBlock variables can be named to be more descriptive if required. There can also be cases depending on the method used where more than one block variable may be defined.\n\nFor instance, when working with a `hash` the key and the value of an item can be accessed with a block variable:\n\n```ruby\nscores = [low: 2, high: 8, average: 6]\n\nscores.each do |key, value|\n  puts \"#{key.capitalize}: #{v}\"\nend\n```\n\n### Block Variable Scope\n\nA [block variable is referenced much like a local variable](#variable-scope-indicators), however, it won't be available to use outside the block:\n\n```ruby\n# Local variable, can be used inside or outside the block.\nfactor = 2\n5.times do |number|\n  # A block variable can only be use inside its block.\n  puts number * factor\nend\n\n# This variable does not exist in the local scope.\nputs number  # undefined local variable or method\n```\n\nIn the case that a `number` variable is defined within the local scope, that value will be used, not the block variable one:\n\n```ruby\n# Local variable, can be used inside or outside the block.\nnumber = 1\nfactor = 2\n5.times do |number|\n  # A block variable can only be use inside its block.\n  puts number * factor\nend\n\n# Variable was declared in local scope and therefore can be accessed.\nputs number  # 1\n```\n\nCode blocks allow a block of code to be defined and be applied to a method.\n\n## Find Methods\n\nRuby's find methods can be applied to enumerables and code blocks when sifting through a set.\n\nA list of the most common methods applied to enumerables include:\n\n- `find` / `detect`\n- `find_all` / `select`\n- `any?` / `none?`\n- `all?` / `one?`\n- `delete_if`\n\nAn example would be to find a value on an enumerable:\n\n```ruby\n# enumerables-and-code-blocks/find-methods.rb\nrange = 1..10\nrange.find {|number| number == 5 } # 5\n```\n\nSince number 5 does exist in the range, the condition is met and the value is returned. [See find-methods.rb](enumerables-and-code-blocks/find-methods.rb) for more examples on how to use find methods.\n\n## Map Methods\n\nIn Ruby, `map` and `collect` can be used to apply changes to each item on an enumerable. Mapping does a few things:\n\n- Iterates through an enumerable.\n- Execute a code block on each item.\n- Add the result of the block to a new array.\n- Returns the same number of items.\n\nIn the example below, `map` will iterate through a block and\nthe code block will make a change to each item:\n\n```ruby\n# enumerables-and-code-blocks/map-methods.rb\nx = [1,2,3,4,5]\ny = x.map {|number| number + 1}\n```\n\nWhilst `x` had the numbers 1 to 5 in an array, `y` will return `[2,3,4,5,6]` instead. The same number of items as `x` but `1` was added to each of the values during the map.\n\nMapping will always return an array, even if a hash is used.\n\n```ruby\n# enumerables-and-code-blocks/map-methods.rb\nscores = {low: 2, high: 8, average: 6}\nadjusted_scores = scores.map do |key,value|\n  \"#{key.capitalize}: #{value * 100}\"\nend\n\nputs adjusted_scores\n```\n\nThe block would result in `adjusted_scores` being returned as an array:\n\n```ruby\n['Low: 200', 'High: 800', 'Average: 600']\n```\n\nThere are also versions with `!` at the end, `map!` and `collect!`. This is the way for Ruby to indicate a more powerful or destructive version of a method. \n\nIn this case it works the exact same way but it replaces the contents of the existing array, modifying it instead of returning a new one.\n\n```ruby\n# enumerables-and-code-blocks/map-methods.rb\nfruits.map! do |fruit|\n  fruit.capitalize\nend\nputs fruits\n```\n\nMapping is a tool that is commonly used in Ruby scripts.\n\n## Inject Methods\n\nInject methods can be useful when reusing the current value of an item on the next iteration but it can be tricky to understand at first.\n\nThe methods are defined as `inject` and its synonym, `reduce`. The key part of an inject method is having an \"accumulator\" value that it uses as it iterates through an enumerable.\n\nThe accumulator is defined as a block variable and the Ruby convention is to name it `memo`.\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\n(1..5).inject {|memo, number| memo + number}\n```\n\nIn the first iteration, `memo` does not have a value and takes the first item of the enumerable instead.\n\nOn subsequent iterations it does `memo + number`, which eventually results on the sum of all the items in this case (15).\n\nHere's a breakdown of the operation:\n\n```ruby\nmemo = 1 # 1\nmemo = memo + 2 # 3\nmemo = memo + 3 # 6\nmemo = memo + 4 # 10\nmemo = memo + 5 # 15\n```\n\nReturn values do matter when using inject methods. Considering the following statement:\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\nnumbers = (1..5).inject do |memo, number|\n  memo + number\n  x = 0\nend\n```\n\nSince the return value of the block is `0`, that is what `memo` will be set to on each iteration.\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\n(1..5).inject do |memo, number|\n  memo + number\n  x = 0\nend\n```\n\nInject can iterate through string items as well and a starting value can be provided which can be helpful when the item is not an integer:\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\nfruits = ['mango', 'pineapple', 'papaya', 'guava']\n\nsize = fruits.inject(0) do |memo, fruit|\n  memo + fruit.length\nend\n```\n\nThis code block will result in the length of all fruits being added together and returning an integer but `inject` is not restricted to returning numbers only:\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\nlongest = fruits.inject do |memo, fruit|\n  if fruit.length \u003e memo.length\n    fruit\n  else\n    memo\n  end\nend\n```\n\nAn empty string can also be passed when manipulating values and storing them in `memo`:\n\n```ruby\n# enumerables-and-code-blocks/inject-methods.rb\nmash = fruits.inject('') do |memo, fruit|\n  memo \u003c\u003c fruit[0]\nend\n```\n\n## Sort Methods\n\nEnumerables can also be sorted. The `sort` method can be used with no arguments to return an array with default sorting:\n\n```ruby\n# enumerables-and-code-blocks/sort-methods.rb\nfruits = ['mango', 'pineapple', 'papaya', 'guava', 'apricot']\ndefault_sort = fruits.sort # [apricot, guava, mango, papaya, pineapple]\n```\n\nThe default sorting for strings is alphabetical sorting in ascending order. This behaviour can be overriden by passing a code block with a comparison, using the comparison operator (`\u003c=\u003e`). This operator can be applied to two values (`value_1 \u003c=\u003e value_2`) and returns one of three values:\n\n| Return value | Meaning | Example | Sort move |\n| ------------- |:-------------:|:-------------:|:-------------:|\n| -1 | Less than | `1 \u003c=\u003e 2` | Moves \"left\" |\n| 0     | Equal | `2 \u003c=\u003e 2` | Stays |\n| 1 | Greater than | `2 \u003c=\u003e 1`| Moves \"right\" |\n\nUsing the comparison operator in a code block allows sorting an enumerable in a custom way:\n\n```ruby\n# enumerables-and-code-blocks/sort-methods.rb\nlength_sort = fruits.sort do |fruit_1, fruit_2|\n  fruit_1.length \u003c=\u003e fruit_2.length\nend # [mango, guava, papaya, apricot, pineapple]\n```\n\nFurthermore there is `sort_by` which allows sorting based on a single property. However, `sort` tends to be slightly faster:\n\n```ruby\n# enumerables-and-code-blocks/sort-methods.rb\nfruits.sort_by {|fruit| fruit.length} # [mango, guava, papaya, apricot, pineapple]\n```\n\nBoth methods have a `!` version that can be used to sort enumerables in place, replacing its contents:\n\n```ruby\n# enumerables-and-code-blocks/sort-methods.rb\nfruits = ['mango', 'pineapple', 'papaya', 'guava', 'apricot']\n\nfruits.sort!\nputs fruits # [apricot, guava, mango, papaya, pineapple]\n\nfruits.sort_by! {|fruit| fruit.length}\nputs fruits # [guava, mango, papaya, apricot, pineapple]\n```\n\nSorting hashes present a problem since it is an unordered set. Sort can be called on a `hash` but it will return an `array`, an ordered set.\n\nThe way it works is by converting the hash into an array and then calling `sort` on it. The position of the values being compared needs to be specified (key or value):\n\n```ruby\n# enumerables-and-code-blocks/sort-methods.rb\nhash = {a:4, y:1, c:5, b:3}\n\n# Sorts by key\nhash.sort do |pair_1, pair_2|\n  pair_1[0] \u003c=\u003e pair_2[0]\nend\n\n# Sorts by value\nhash.sort do |pair_1, pair_2|\n  pair_1[1] \u003c=\u003e pair_2[1]\nend\n```\n\n## Merge Methods\n\nMerge methods only apply to hashes and are able to merge two of them together. Takes the keys and values of one `hash` and another to form a new `hash`. A block can be provided in order to define rules to be used when performing the merge.\n\n```ruby\n# enumerables-and-code-blocks/merge-methods.rb\nhash_1 = {:a =\u003e 2, :b =\u003e 4, :c =\u003e 6}\nhash_2 = {:a =\u003e 3, :b =\u003e 4, :d =\u003e 8}\n\nhash_1.merge(hash_2) # {:a =\u003e 3, :b =\u003e 4, :c =\u003e 6, :d =\u003e 8}\n```\n\nIn the example above, two hashes were merged. There were no conflicts except with the value of `hash_1[:a]` and `hash_2[:a]` as those were different.\n\nThe merge method chose to get the value of the hash being merged in by default but this can be overridden with a code block. Ruby will make use of the code block in the case of a key conflict.\n\n```ruby\n# enumerables-and-code-blocks/merge-methods.rb\nhash_1.merge(hash_2) {|key,old,new| old} # {:a =\u003e 2, :b =\u003e 4, :c =\u003e 6, :d =\u003e 8}\n```\n\nBlocks are not limited to returning those values, they can also be used to return a value based on a comparison or operation:\n\n```ruby\n# Further logic can be applied to determine which value should be returned.\nputs hash_1.merge(hash_2) {|key,old,new| old \u003c new ? old : new } # {:a =\u003e 2, :b =\u003e 4, :c =\u003e 6, :d =\u003e 8}\n\n\n# Both values can be used and assigned to a key.\nputs hash_1.merge(hash_2) {|key,old,new| old * new } # {:a =\u003e 6, :b =\u003e 16, :c =\u003e 6, :d =\u003e 8}\n```\n\nSince `:b` also presents a `key` conflict even if they have the same values, the block logic also applies to it.\n\nThe merge method also has a `merge!` version which replaces the contents of a hash.\n\n\u003e There's a challenge available for this chapter: [Ruby Blanks](challenges/ruby-blanks.rb)\n\n# Custom Methods\n\nThis chapter is focused on introducing concepts to create and work with Ruby's custom methods.\n\n## Define and Call Methods\n\nMethods were already mentioned in previous chapters and how they can be applied to other objects. For instance, the use of `reverse`, `each` and `sort`, methods that are predefined on Ruby objects.\n\nThis section will go over how to define can call custom methods. Methods, called functions in other programming languages, are going to provide instructions to perform a specific task which have been packaged up as a unit, and can be called later in a script, multiple times.\n\nThis allows the _\"Do not Repeat Yourself\"_ (DRY) paradigm to be applied as a method is defined once and called as needed, instead of being rewritten multiple times.\n\nIn Ruby, methods have to be defined before they can be called and can be redefined without error. Usually, on other programming languages a method/function cannot be redeclared at any point, this is not the case with Ruby.\n\nGenerally, methods will be named in lowercase, with words separated by underscores (`my_ruby_method`) and the _first_ character has always to be either lowercase or an underscore, the latter is uncommon.\n\nAny other character can be a letter, digit or underscore, with the exception of the last character which can also be a `?`, `!` or `=`.\n\nAdditionally, using the same names for variables and methods should be avoided as it can be confusing.\n\n### Method Definition\n\nA method can be defined with the keywords `def` and `end` as follows:\n\n```ruby\ndef method_name\n  # code here...\nend\n```\n\nAfter being defined, a method can be called as follows:\n\n```ruby\n# Executes the method.\nmethod_name\n```\n\nA more complete method shows how arguments can be passed in:\n\n```ruby\n# custom-methods/define-and-call-methods.rb\ndef greet(name)\n  puts \"Hello, #{name}\"\nend\n\ngreet('Skoglund') # Hello, Skoglund\n```\n\nA method doesn't need to have arguments, but if it does, different data can be passed in each time it's called.\n\n## Variable Scope\n\nThis section expands on the concept of variable scope, as in where variables can be accessed from in a script depending on how they get defined.\n\nWhen a variable is defined without any [scope indicators](#variables), it defaults to a local variable. A variable defined inside a method is also considered a local variable, however, it cannot be accessed outside the method, the same way a local variable defined outside a method cannot be used inside one.\n\n\u003e Local variables inside methods only have scope inside methods.\n\nGlobal, class and instance variables will have scope both outside and inside methods. This will be [expanded on at a later chapter](https://github.com/csalmeida/ruby-classes-and-modules).\n\n```ruby\n# custom-methods/variable-scope.rb\nvalue = 10\n\ndef output_value\n  value = 5\n  puts value\nend\n\noutput_value # Will print 5, not 10.\nputs value # Will print 10, not 5.\n```\n\nThe example above shows how two variables called `value` were defined and are different as they belong to different local scopes. `value = 10` is scoped to the wider structure of the document whilst `value = 5` is scoped to the `output_value` method.\n\n## Arguments\n\nArguments, also referred to as `args`, allow a method to receive values at runtime (when it is called). Multiple arguments can be defined in a method, and these are separated by commas.\n\nThe order and number of arguments passed in must match the method definition. In the example below, the `volume` method expects three arguments:\n\n```ruby\n# custom-methods/arguments.rb\ndef volume(x, y, z)\n  x * y * z\nend\n\nvolume(2,3,4) # 24\n```\n\nArguments can be used to add dynamism to scripts, as methods can be called with different values each time:\n\n```ruby\n# custom-methods/arguments.rb\nvolume(5,7,8) # 280\nvolume(42,86,22) # 79464\n```\n\nThe method requires all arguments to be passed in, otherwise it will throw an error:\n\n```ruby\nvolume(42,86)\n# custom-methods/arguments.rb:4:in `volume': wrong number of arguments (given 2, expected 3) (ArgumentError)\n```\n\nIt will also expect arguments to be passed in the correct order, otherwise unexpected behavior might occur:\n\n```ruby\n# custom-methods/arguments.rb\ndef introduction(greeting, name)\n  puts \"#{greeting}, #{name}.\"\nend\n\nintroduction(\"Yoda\",\"I am\") # \"Yoda, I am.\"\nintroduction(\"I am\",\"Groot\") # \"I am, Groot.\"\n```\n\nThe convention in Ruby is that methods should only have parentheses if they take arguments, whether they're being defined or called:\n\n```ruby\n# Parentheses being used to wrap arguments:\ndef introduction(greeting, name)\n  puts \"#{greeting}, #{name}.\"\nend\n\nintroduction(\"Yoda\",\"I am\")\n\n# The same being done with a method with no arguments.\n# Uncommon, but valid Ruby.\ndef welcome()\n  puts \"Hello!\"\nend\n\nwelcome()\n\n# A method with no arguments is usually defined and called with no parentheses.\ndef goodbye\n  puts \"Hello!\"\nend\n\ngoodbye\n\n# However, methods with arguments can also refrain from using parentheses.\n# This is discouraged and considered bad practice by some Rubyists, but some might define and call methods this way.\ndef call name\n  puts \"#{name}!\"\nend\n\ncall 'puppy'\n```\n\n### Argument Default Values\n\nArguments can be made optional, in case they're not present a default value will be put in place instead. It can take any Ruby object as an optional argument:\n\n```ruby\ndef greet(greeting=\"Hello\", name=\"World\")\n  puts \"#{greeting}, #{name}\"\nend\n\ngreet() # \"Hello, World\"\n```\n\nRequired arguments should be listed first as those need to be passed in, whilst optional ones are listed last. \n\nHowever, if a default value needs be skipped over, usually the optional arguments are passed in as a `hash` in order to provider further flexibility:\n\n```ruby\n# custom-methods/arguments.rb\nwelcome_options = {\n  name: \"Geralt\",\n  punctuation: \"...\"\n}\n\ndef welcome(greeting, options={})\n  name = options[:name] || 'friend'\n  punct = options[:punctuation] || '!'\n  greeting + ' ' + name + punct\nend\n\nputs welcome(\"It's you,\", welcome_options); # It's you, Geralt...\nputs welcome(\"Hello\"); # Hello friend!\n```\n\n## Return\n\nMethods return values, and in Ruby the last operation's value in the code block is the one returned by default. For instance, in the example below, `y + z` is the value returned:\n\n```ruby\ndef custom_method(x,y,z)\n  x + y\n  z + x\n  y + z\nend\n```\n\nThe last operation's value is the one returned. This can lead to pitfalls in cases where conditionals take place:\n\n```ruby\n# custom-methods/return.rb\ndef subtract(number_1, number_2)\n  result = number_1 - number_2\n  result = 0 if result \u003c 5\nend\n\nputs subtract(8, 3) # nil\n```\n\nIt is not required in Ruby for the `return` keyword to be used in the last line of the method. In some cases, a return value might be required to be declared explicitly. This can be done with the `return` keyword and it can be useful when applying `if` statements and loops and there's the need to return early.\n\n```ruby\n# custom-methods/return.rb\ndef greet_again(cool = false)\n  if cool\n    return greeting = \"Yo\"\n  end\n  greeting = \"Hello\"\nend\n\ncool = true\nputs greet_again(cool)\n```\n\nAdditionally, `puts` and `print` should be avoided in most methods as it makes them more flexible. The return value can be assigned to a variable or interpolated into a string.\n\nIt is recommended to have separate methods to make calculations and another for output.\n\n### Return Multiple Values\n\nMethods are able to return only one object. If more than one value needs to be returned, they need to be stored in an object enumerable like a `hash` or an `array`.\n\n```ruby\n# custom-methods/return.rb\ndef add_and_subtract(number_1, number_2)\n  add = number_1 + number_2\n  subtract = number_1 - number_2\n  [add, subtract]\nend\n```\n\nFurthermore, the values can be assigned to variables using Ruby's multitple assignment feature. It takes array values and assign them to each variable:\n\n```ruby\nadd_result, sub_result = add_and_subtract(15,2)\nputs \"Addition result was #{add_result} whilst subtraction was #{sub_result}.\"\n```\n\n\u003e There's a challenge available for this chapter: [Pig Latin](challenges/pig-latin.rb)\n\n# Further Resources\n\n- [Ruby: Classes and Modules Repository (continuation of Ruby Fundamentals)](https://github.com/csalmeida/ruby-classes-and-modules)\n- [Ruby: Classes and Modules LinkedIn Course](https://www.linkedin.com/learning/ruby-classes-and-modules/define-a-class)\n- [Ruby on Rails](https://rubyonrails.org/)\n- [Ruby API Documentation](https://rubyapi.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsalmeida%2Fruby-fundamentals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsalmeida%2Fruby-fundamentals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsalmeida%2Fruby-fundamentals/lists"}