├── Chapter01
└── do_I_have_ruby.rb
├── Chapter02
├── global_variable.rb
└── variable_types.rb
├── Chapter08
├── if_elsif.rb
├── ifelsif_syntax.rb
└── unless_syntax.rb
├── Chapter09
├── api_connector.rb
├── initializer_section
│ └── api_connector.rb
├── instantiation_example.rb
├── isp_section
│ └── blog.rb
├── lsp_section
│ └── lsp_example.rb
├── oop_inheritance_section
│ └── api_connector.rb
├── open_closed_principle
│ └── order_report.rb
├── polymorphism_section
│ └── api_connector.rb
└── srp_example
│ ├── mailer_class.rb
│ ├── sales_tax_class.rb
│ └── srp.rb
├── Chapter10
└── files-lessons
│ ├── creating_a_file.rb
│ └── creating_log_file.rb
├── Chapter11
├── best_practice
│ └── error_handling.rb
├── error_handling_tutorial
│ └── error_handling.rb
└── error_logger
│ └── error-handling-lessons
│ └── error_logger.rb
├── Chapter15
├── dmethod.rb
├── mmissing.rb
└── respond_to.rb
├── Chapter17
├── api_example.rb
└── custom_api_connector.rb
├── Chapter18
├── amicable_number.rb
├── bubble_sort.rb
├── date_algorithm.rb
├── factorial_algorithm.rb
├── fibonacci_alogrithm.rb
├── fibonacci_digit_counter.rb
├── merge_sort.rb
├── prime_counting_algorithm.rb
└── quick_sort.rb
├── LICENSE
└── README.md
/Chapter01/do_I_have_ruby.rb:
--------------------------------------------------------------------------------
1 | puts "Yes, you have Ruby!"
--------------------------------------------------------------------------------
/Chapter02/global_variable.rb:
--------------------------------------------------------------------------------
1 | 10.times do
2 | $x = 10
3 | end
4 |
5 | p $x
--------------------------------------------------------------------------------
/Chapter02/variable_types.rb:
--------------------------------------------------------------------------------
1 | 10.times do
2 | x = 10
3 | p x
4 | end
--------------------------------------------------------------------------------
/Chapter08/if_elsif.rb:
--------------------------------------------------------------------------------
1 | x = 10
2 | y = 100
3 | z = 10
4 |
5 | if x == y && x == z
6 | puts "from the if statement"
7 | end
--------------------------------------------------------------------------------
/Chapter08/ifelsif_syntax.rb:
--------------------------------------------------------------------------------
1 | x = 10
2 | y = 100
3 | z = 10
4 |
5 | if x == y
6 | puts "x is equal to y"
7 | elsif x > z
8 | puts "x is greater than z"
9 | else
10 | puts "Something else"
11 | end
--------------------------------------------------------------------------------
/Chapter08/unless_syntax.rb:
--------------------------------------------------------------------------------
1 | players = ["Correa", "Carter", "Altuve"]
2 | unless players.empty?
3 | players.each{ |player| puts player }
4 | end
--------------------------------------------------------------------------------
/Chapter09/api_connector.rb:
--------------------------------------------------------------------------------
1 | class ApiConnector
2 | attr_accessor :title , :description , :url
3 |
4 | def test_method
5 | puts "testing class call"
6 | end
7 | end
8 |
9 | api = ApiConnector .new
10 | api.url = "http://google.com/"
11 | puts api.url
12 | api.test_method
--------------------------------------------------------------------------------
/Chapter09/initializer_section/api_connector.rb:
--------------------------------------------------------------------------------
1 | class ApiConnector
2 | def initialize(title, description, url)
3 | @title = title
4 | @description = description
5 | @url = url
6 | end
7 | def testing_initializer
8 | puts @title
9 | puts @description
10 | puts @url
11 | end
12 | end
13 |
14 | api = ApiConnector.new("My title", "My cool description", "google.com")
--------------------------------------------------------------------------------
/Chapter09/instantiation_example.rb:
--------------------------------------------------------------------------------
1 | class Invoice
2 | attr_accessor:customer, :total
3 |
4 | def summary
5 | puts "Invoice:"
6 | puts "Customer: #{customer}"
7 | puts "Total: #{total}"
8 | end
9 | end
10 |
11 | invoice = Invoice.new
12 | invoice.customer = "Google"
13 | invoice.total = 500
14 | invoice.summary
--------------------------------------------------------------------------------
/Chapter09/isp_section/blog.rb:
--------------------------------------------------------------------------------
1 | class Blog
2 | def edit_post
3 | puts "Post edited"
4 | end
5 |
6 | def delete_post
7 | puts "Post removed"
8 | end
9 |
10 | def create_post
11 | puts "Post created"
12 | end
13 | end
14 |
15 | blog = Blog.new
16 | blog.edit_post
17 | blog.delete_post
18 | blog.create_post
--------------------------------------------------------------------------------
/Chapter09/lsp_section/lsp_example.rb:
--------------------------------------------------------------------------------
1 | require 'date'
2 |
3 | class User
4 | attr_accessor :settings, :email
5 |
6 | def initialize(email:)
7 | @email = email
8 | end
9 | end
10 |
11 | class AdminUser < User
12 | end
13 |
14 | user = User.new(email: "user@test.com")
15 | user.settings = {
16 | level: "Low Security",
17 | status: "Live",
18 | signed_in: Date.today
19 | }
20 |
21 | admin = AdminUser.new(email: "admin@test.com")
22 | admin.settings = ["Editor", "VIP", Date.today]
23 |
24 | puts user.settings
25 | puts admin.settings
--------------------------------------------------------------------------------
/Chapter09/oop_inheritance_section/api_connector.rb:
--------------------------------------------------------------------------------
1 | class ApiConnector
2 | def initialize(title:, description:, url: 'google.com')
3 | @title = title
4 | @description = description
5 | @url = url
6 | end
7 | end
8 |
9 | class SmsConnector < ApiConnector
10 | def send_sms
11 | puts "Sending SMS message..."
12 | end
13 | end
14 |
15 | class MailerConnector < ApiConnector
16 | def send_mail
17 | puts "Sending mail message..."
18 | end
19 | end
20 |
21 | class PhoneConnector < ApiConnector
22 | def place_call
23 | puts "Placing phone call..."
24 | end
25 | end
26 |
27 | class XyzConnector < ApiConnector
28 | def does_something_else
29 | puts "Secret stuff..."
30 | end
31 | end
32 |
33 | sms = SmsConnector.new(title: "Hi there!", description: "I'm in a SMS message")
34 | mail = MailerConnector.new(title: "Hi there!", description: "I'm in an email message")
35 | phone = PhoneConnector.new(title: "Hi there!", description: "I'm on a call")
36 | xyz = XyzConnector.new(title: "Hi there!", description: "Who knows what I'm in")
37 |
38 | sms.send_sms
39 | mail.send_mail
40 | phone.place_call
41 | xyz.does_something_else
--------------------------------------------------------------------------------
/Chapter09/open_closed_principle/order_report.rb:
--------------------------------------------------------------------------------
1 | class OrderReport
2 | def initialize(customer:, total:)
3 | @customer = customer
4 | @total = total
5 | end
6 |
7 | def invoice
8 | puts "Invoice"
9 | puts @customer
10 | puts @total
11 | end
12 |
13 | def bill_of_lading
14 | puts "BOL"
15 | puts @customer
16 | puts "Shipping Label..."
17 | end
18 | end
19 |
20 | order = OrderReport.new(customer: "Google", total: 100)
21 | order.invoice
22 | order.bill_of_lading
--------------------------------------------------------------------------------
/Chapter09/polymorphism_section/api_connector.rb:
--------------------------------------------------------------------------------
1 | class ApiConnector
2 | def initialize(title:, description:, url: 'google.com')
3 | @title = title
4 | @description = description
5 | @url = url
6 | end
7 |
8 | def api_logger
9 | puts "API Connector starting..."
10 | end
11 | end
12 |
13 | class PhoneConnector < ApiConnector
14 | def api_logger
15 | super
16 | puts "Phone call API connection starting..."
17 | end
18 | end
19 |
20 | phone = PhoneConnector.new(title: 'My Title', description: 'Some content')
21 | phone.api_logger
--------------------------------------------------------------------------------
/Chapter09/srp_example/mailer_class.rb:
--------------------------------------------------------------------------------
1 | class Invoice
2 | def initialize(customer:, state:, total:)
3 | @customer = customer
4 | @state = state
5 | @total = total
6 | end
7 |
8 | def details
9 | "Customer: #{@customer}, Total: #{@total}"
10 | end
11 |
12 | def sales_tax
13 | case @state
14 | when 'AZ' then 5.5
15 | when 'TX' then 3.2
16 | when 'CA' then 8.7
17 | end
18 | end
19 | end
20 |
21 | class Mailer
22 | def self.email(content)
23 | puts "Emailing..."
24 | puts content
25 | end
26 | end
27 |
28 | invoice = Invoice.new(customer: "Google", state: "AZ", total: 100)
29 | puts invoice.sales_tax
30 | Mailer.email(invoice.details)
--------------------------------------------------------------------------------
/Chapter09/srp_example/sales_tax_class.rb:
--------------------------------------------------------------------------------
1 | class Invoice
2 | def initialize(customer:, state:, total:)
3 | @customer = customer
4 | @total = total
5 | end
6 |
7 | def details
8 | "Customer: #{@customer}, Total: #{@total}"
9 | end
10 | end
11 |
12 | class SalesTax
13 | def initialize(state:)
14 | @state = state
15 | end
16 |
17 | def sales_tax
18 | case @state
19 | when 'AZ' then 5.5
20 | when 'TX' then 3.2
21 | when 'CA' then 8.7
22 | end
23 | end
24 | end
25 |
26 | class Mailer
27 | def self.email(content)
28 | puts "Emailing..."
29 | puts content
30 | end
31 | end
32 |
33 | invoice = Invoice.new(customer: "Google", state: "AZ", total: 100)
34 | tax = SalesTax.new(state: 'CA')
35 | puts tax.sales_tax
36 | Mailer.email(invoice.details)
--------------------------------------------------------------------------------
/Chapter09/srp_example/srp.rb:
--------------------------------------------------------------------------------
1 | class Invoice
2 | def initialize(customer:, state:, total:)
3 | @customer = customer
4 | @state = state
5 | @total = total
6 | end
7 |
8 | def details
9 | "Customer: #{@customer}, Total: #{@total}"
10 | end
11 |
12 | def sales_tax
13 | case @state
14 | when 'AZ' then 5.5
15 | when 'TX' then 3.2
16 | when 'CA' then 8.7
17 | end
18 | end
19 |
20 | def email_invoice
21 | puts "Emailing invoice..."
22 | puts details
23 | end
24 | end
25 |
26 | invoice = Invoice.new(customer: "Google", state: "AZ", total: 100)
27 | puts invoice.sales_tax
28 | invoice.email_invoice
--------------------------------------------------------------------------------
/Chapter10/files-lessons/creating_a_file.rb:
--------------------------------------------------------------------------------
1 | File.open("files-lessons/teams.txt" , 'w+') { |f| f.write("Twins, Astros, Mets, Yankees") }
--------------------------------------------------------------------------------
/Chapter10/files-lessons/creating_log_file.rb:
--------------------------------------------------------------------------------
1 | 10.times do
2 | sleep 1
3 | puts "Record saved..."
4 | File.open("files-lessons/server_logs.txt", "a") {|f|
5 | f.puts"Server started at: #{Time.new}"}
6 | end
--------------------------------------------------------------------------------
/Chapter11/best_practice/error_handling.rb:
--------------------------------------------------------------------------------
1 | begin
2 | puts 8/0
3 | rescue ZeroDivisionError => e
4 | puts "Error occurred: #{e}"
5 | end
--------------------------------------------------------------------------------
/Chapter11/error_handling_tutorial/error_handling.rb:
--------------------------------------------------------------------------------
1 | begin
2 | puts 8/0
3 | rescue
4 | puts "Rescued the error"
5 | end
--------------------------------------------------------------------------------
/Chapter11/error_logger/error-handling-lessons/error_logger.rb:
--------------------------------------------------------------------------------
1 | def error_logger (e)
2 | File.open('error-handling-lessons/error_log.txt', 'a') do |file|
3 | file.puts e
4 | end
5 | end
--------------------------------------------------------------------------------
/Chapter15/dmethod.rb:
--------------------------------------------------------------------------------
1 | class Author
2 | define_method("some_method") do
3 | puts "Some details"
4 | end
5 | end
6 |
7 | author = Author.new
8 | author.some_method
9 |
10 | class Author
11 | genres = %w(fiction coding history)
12 |
13 | genres.each do |genre|
14 | define_method("#{genre}_details") do |arg|
15 | puts "Genre: #{genre}"
16 | puts arg
17 | puts genre.object_id
18 | end
19 | end
20 | end
21 |
22 | author = Author.new
23 | author.fiction_details "Ayn Rand"
24 | author.coding_details "Cal Newport"
--------------------------------------------------------------------------------
/Chapter15/mmissing.rb:
--------------------------------------------------------------------------------
1 | require 'ostruct'
2 |
3 | class Author
4 | attr_accessor :first_name, :last_name, :genre
5 |
6 | def author
7 | OpenStruct.new(first_name: first_name, last_name: last_name, genre: genre)
8 | end
9 |
10 | def method_missing(method_name, *arguments, &block)
11 | if method_name.to_s =~ /author_(.*)/
12 | author.send($1, *arguments, &block)
13 | else
14 | super
15 | end
16 | end
17 | end
18 |
19 | author = Author.new
20 | author.first_name = "Cal"
21 | author.last_name = "Newpot"
22 | author.genre = "Computer Science"
23 |
24 | p author.author_genre
25 | p author.respond_to?(:author_genre)
--------------------------------------------------------------------------------
/Chapter15/respond_to.rb:
--------------------------------------------------------------------------------
1 | require 'ostruct'
2 |
3 | class Author
4 | attr_accessor :first_name, :last_name, :genre
5 |
6 | def author
7 | OpenStruct.new(first_name: first_name, last_name: last_name, genre: genre)
8 | end
9 |
10 | def method_missing(method_name, *arguments, &block)
11 | if method_name.to_s =~ /author_(.*)/
12 | author.send($1, *arguments, &block)
13 | else
14 | super
15 | end
16 | end
17 |
18 | def respond_to_missing?(method_name, include_private = false)
19 | method_name.to_s.start_with?('author_') || super
20 | end
21 | end
22 |
23 | author = Author.new
24 | author.first_name = "Cal"
25 | author.last_name = "Newpot"
26 | author.genre = "Computer Science"
27 |
28 | p author.author_genre
29 | p author.respond_to?(:author_genre)
--------------------------------------------------------------------------------
/Chapter17/api_example.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'httparty'
3 |
4 | class EdutechionalResty
5 | include HTTParty
6 | base_uri "http://edutechional-resty.herokuapp.com"
7 |
8 | def posts
9 | self.class.get('/posts.json')
10 | end
11 | end
12 |
13 | api = EdutechionalResty.new
14 | puts api.posts
--------------------------------------------------------------------------------
/Chapter17/custom_api_connector.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'httparty'
3 |
4 | class StackExchange
5 | include HTTParty
6 | base_uri 'api.stackexchange.com'
7 |
8 | def initialize(service, page)
9 | @options = { query: {site: service, page: page}}
10 | end
11 |
12 | def questions
13 | self.class.get('/2.2/questions', @options)
14 | end
15 |
16 | def users
17 | self.class.get('/2.2/users', @options)
18 | end
19 | end
20 |
21 | stack_exchange = StackExchange.new('stackoverflow', 1)
22 | puts stack_exchange.questions
--------------------------------------------------------------------------------
/Chapter18/amicable_number.rb:
--------------------------------------------------------------------------------
1 | require 'mathn'
2 |
3 | class Integer
4 | def dsum
5 | return 1 if self < 2
6 | pd = prime_division.flat_map{|n,p| [n] * p}
7 | ([1] + (1...pd.size).flat_map{ |e| pd.combination(e).map{
8 | |f| f.reduce(:*)
9 | }}).uniq.inject(:+)
10 | end
11 | end
12 |
13 | def find_d_sum(n)
14 | n.times.inject do |sum, cur|
15 | other = cur.dsum
16 | (cur != other && other.dsum == cur) ? sum + cur :sum
17 | end
18 | end
19 |
20 | p find_d_sum(10_000)
21 |
--------------------------------------------------------------------------------
/Chapter18/bubble_sort.rb:
--------------------------------------------------------------------------------
1 | def bubble_sort array
2 | n = array.length
3 | loop do
4 | swapped = false
5 | (n-1).times do |i|
6 | if array[i] > array[i+1]
7 | array[i], array[i+1]=array[i+1], array[i]
8 | swapped = true
9 | end
10 | end
11 | break if not swapped
12 | end
13 | array
14 | end
15 |
16 | a = [1, 4, 1, 3, 4, 1, 3, 3]
17 | p bubble_sort(a)
--------------------------------------------------------------------------------
/Chapter18/date_algorithm.rb:
--------------------------------------------------------------------------------
1 | require 'date'
2 |
3 | start_date = Time.local(1901)
4 | end_date = Time.local(2000,12,31)
5 | sunday_counter = 0
6 |
7 | while end_date>= start_date
8 | if end_date.strftime("%A") == "Sunday"&&
9 | end_date.strftime("%d") == "01"
10 | sunday_counter += 1
11 | end
12 | end_date -= 86400
13 | end
14 | puts sunday_counter
--------------------------------------------------------------------------------
/Chapter18/factorial_algorithm.rb:
--------------------------------------------------------------------------------
1 | def factorial_value_sum_generator(factorial)
2 | arr = (1..factorial).to_a.reverse.each {
3 | |i| factorial += factorial * (i - 1)}
4 | factorial.to_s.split(//).map(&:to_i).inject(:+)
5 | end
6 |
7 | p factorial_value_sum_generator(100)
--------------------------------------------------------------------------------
/Chapter18/fibonacci_alogrithm.rb:
--------------------------------------------------------------------------------
1 | class Fibbing
2 | def initialize(max)
3 | @num_1 = 0
4 | @i = 0
5 | @sum = 0
6 | @num_2 = 1
7 | @max = max
8 | end
9 | def even_fibonacci
10 | while @i<= @max
11 | @i = @num_1 + @num_2
12 | @sum += @i if@i % 2 == 0
13 | @num_1 = @num_2
14 | @num_2 = @i
15 | end
16 | @sum
17 | end
18 | end
19 |
20 | result = Fibbing.new(4_000_000)
21 | p result.even_fibonacci
--------------------------------------------------------------------------------
/Chapter18/fibonacci_digit_counter.rb:
--------------------------------------------------------------------------------
1 | def fibonacci_digit_counter
2 | num1, num2, i = -1, 0, 1
3 | while i.to_s.length < 1000
4 | num1 += 1
5 | i, num2 = num2, num2 + i
6 | end
7 | num1
8 | end
9 |
10 | p fibonacci_digit_counter
--------------------------------------------------------------------------------
/Chapter18/merge_sort.rb:
--------------------------------------------------------------------------------
1 | def merge(left, right)
2 | if left.empty?
3 | right
4 | elsif right.empty?
5 | left
6 | elsif left.first < right.first
7 | [left.first] + merge(left[1..left.length], right)
8 | else
9 | [right.first] + merge(left, right[1..right.length])
10 | end
11 | end
12 |
13 | def merge_sort(list)
14 | if list.length <= 1
15 | list
16 | else
17 | mid = (list.length / 2).floor
18 | left = merge_sort(list[0..mid - 1])
19 | right = merge_sort(list[mid..list.length])
20 | merge(left, right)
21 | end
22 | end
23 |
24 | arr = [4, 1, 5, 1, 33, 312]
25 | p merge_sort(arr)
--------------------------------------------------------------------------------
/Chapter18/prime_counting_algorithm.rb:
--------------------------------------------------------------------------------
1 | require 'prime'
2 |
3 | prime_array = Prime.take_while { |p| p <2_000_000 }
4 | total_count = prime_array.inject { |sum, x| sum + x }
5 | puts total_count
--------------------------------------------------------------------------------
/Chapter18/quick_sort.rb:
--------------------------------------------------------------------------------
1 | class Array
2 | def quicksort
3 | return [] if empty?
4 | pivot = delete_at(rand(size))
5 | left, right = partition(&pivot.method(:>))
6 | return *left.quicksort, pivot, *right.quicksort
7 | end
8 | end
9 |
10 | arr = [34, 2, 1, 5, 3]
11 | p arr.quicksort
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Comprehensive Ruby Programming
5 | This is the code repository for [Comprehensive Ruby Programming](https://www.packtpub.com/application-development/comprehensive-ruby-programming?utm_source=github&utm_medium=repository&utm_campaign=9781787280649), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish.
6 | ## About the Book
7 | Ruby is a powerful, general-purpose programming language that can be applied to any task. Whether you are an experienced developer who wants to learn a new language or you are new to programming, this book is your comprehensive Ruby coding guide. Starting with the foundational principles, such as syntax, and scaling up to advanced topics such as big data analysis, this book will give you all of the tools you need to be a professional Ruby developer. A few of the key topics are: object-oriented programming, built-in Ruby methods, core programming skills, and an introduction to the Ruby on Rails and Sinatra web frameworks. You will also build 10 practical Ruby programs.
8 |
9 | Created by an experienced Ruby developer, this book has been written to ensure it focuses on the skills you will need to be a professional Ruby developer. After you have read this book, you will be ready to start building real-world Ruby projects.
10 | ## Instructions and Navigation
11 | All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02.
12 |
13 |
14 |
15 | The code will look like the following:
16 | ```
17 | 10.times do
18 | x=10
19 | end
20 |
21 | p x
22 | ```
23 |
24 | This course starts at the beginning with how to install Ruby and work with it on multiple machines, so simply have a computer that's connected to the internet and you'll be ready. I'll also show how to run Ruby programs in the browser, so you can work through this book on any operating system.
25 |
26 | ## Related Products
27 | * [Ruby on Rails for Beginners [Video]](https://www.packtpub.com/web-development/ruby-rails-beginners-video?utm_source=github&utm_medium=repository&utm_campaign=9781787122635)
28 |
29 | * [Ruby on Rails Enterprise Application Development: Plan, Program, Extend](https://www.packtpub.com/web-development/ruby-rails-enterprise-application-development-plan-program-extend?utm_source=github&utm_medium=repository&utm_campaign=9781847190857)
30 |
31 | * [Cloning Internet Applications with Ruby](https://www.packtpub.com/web-development/cloning-internet-applications-ruby?utm_source=github&utm_medium=repository&utm_campaign=9781849511063)
32 |
33 | ### Download a free PDF
34 |
35 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
36 |