├── 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 |

https://packt.link/free-ebook/9781787280649

--------------------------------------------------------------------------------