Polished Ruby Programming - Jeremy Evans - E-Book

Polished Ruby Programming E-Book

Jeremy Evans

0,0
39,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.
Mehr erfahren.
Beschreibung

Anyone striving to become an expert Ruby programmer needs to be able to write maintainable applications.
Polished Ruby Programming will help you get better at designing scalable and robust Ruby programs, so that no matter how big the codebase grows, maintaining it will be a breeze.

This book takes you on a journey through implementation approaches for many common programming situations, the trade-offs inherent in each approach, and why you may choose to use different approaches in different situations.

You'll start by refreshing Ruby fundamentals, such as correctly using core classes, class and method design, variable usage, error handling, and code formatting. Then you'll move on to higher-level programming principles, such as library design, use of metaprogramming and domain-specific languages, and refactoring. Finally, you'll learn principles specific to web application development, such as how to choose a database and web framework, and how to use advanced security features.
By the end of this Ruby programming book, you’ll be a well rounded web developer with a deep understanding of Ruby.

While most code examples and principles discussed in the book apply to all Ruby versions, some examples and principles are specific to Ruby 3.0, the latest release at the time of publication.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 520

Veröffentlichungsjahr: 2021

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Polished Ruby Programming

Build better software with more intuitive, maintainable, scalable, and high-performance Ruby code

Jeremy Evans

BIRMINGHAM—MUMBAI

Polished Ruby Programming

Copyright © 2021 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Group Product Manager: Aaron Lazar

Publishing Product Manager: Alok Dhuri

Senior Editor: Rohit Singh

Content Development Editor: Tiksha Lad

Technical Editor: Pradeep Sahu

Copy Editor: Safis Editing

Project Coordinator: Deeksha Thakkar

Proofreader: Safis Editing

Indexer: Pratik Shirodkar

Production Designer: Shankar Kalbhor

First published: June 2021

Production reference: 2100821

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham

B3 2PB, UK.

ISBN 978-1-80107-272-4

www.packt.com

To Allyson, Jaden, Ruby, Jennifer, and Veronica, who most shaped my life.- Jeremy Evans

Contributors

About the author

Jeremy Evans is a Ruby committer who focuses on fixing bugs in Ruby, as well as improving the implementation of Ruby. He is the maintainer of many popular Ruby libraries, including the fastest web framework (Roda) and fastest database library (Sequel). His libraries are known not just for their performance, but also for their code quality, understandability, documentation, and how quickly any bugs found are fixed. For his contributions to Ruby and the Ruby community, he has received multiple awards, such as receiving the prestigious RubyPrize in 2020 and being chosen as a Ruby Hero in 2015. He has given presentations at over 20 Ruby conferences. In addition to working on Ruby, he is also a committer for the OpenBSD operating system.

I would like to thank the editors, technical reviewers, and other Packt staff for their help in creating this book. I would especially like to thank Janko Marohnić for his reviews and recommendations, which resulted in so many improvements to this book.

About the reviewers

Jagdish Narayandasani has more than 14 years of experience in software development and almost a decade of experience in working on Ruby on Rails. He is currently working as a Technology Specialist with a New York-based Fintech firm. He often contributes as a echnical reviewer for technical books. He has worked on a variety of technologies, such as Java, Ruby, Elixir, and the AWS cloud for different companies. He has worked in various industries, such as finance, retail, healthcare, and wealth management. At the moment, he is trying his hand at blockchain technology. In his free time, he loves to spend time with his family, explore new places, and try new food.

Janko Marohnić is a seasoned Ruby developer with big love for open source. He has authored many Ruby libraries, spoken at conferences, and writes on his blog about his discoveries in the Ruby ecosystem (most of them are libraries created or maintained by the author of this book). He values well-tested code, separation of responsibilities, and doing more with less. Outside of programming, Janko enjoys dancing, acrobatic activities, and playing the piano.

Table of Contents

Preface

Section 1: Fundamental Ruby Programming Principles

Chapter 1: Getting the Most out of Core Classes

Technical requirements

Learning when to use core classes

Best uses for true, false, and nil objects

Different numeric types for different needs

Understanding how symbols differ from strings

Learning how best to use arrays, hashes, and sets

Implementing an in-memory database

Working with Struct – one of the underappreciated core classes

Summary

Questions

Further reading

Chapter 2: Designing Useful Custom Classes

Technical requirements

Learning when to create a custom class

Handling trade-offs in SOLID design

The single-responsibility principle

The open-closed principle

The Liskov substitution principle

The interface segregation principle

The dependency inversion principle

Deciding on larger classes or more classes

Learning when to use custom data structures

Summary

Questions

Chapter 3: Proper Variable Usage

Technical requirements

Using Ruby's favorite variable type – the local variable

Increasing performance by adding local variables

Avoiding unsafe optimizations

Handling scope gate issues

Naming considerations with local variables

Learning how best to use instance variables

Increasing performance with instance variables

Handling scope issues with instance variables

Naming considerations for instance variables

Understanding how constants are just a type of variable

Handling scope issues with constants

Visibility differences between constants and class instance variables

Naming considerations with constants

Replacing class variables

Replacing class variables with constants

Replacing class variables with class instance variables using the superclass lookup approach

Replacing class variables with class instance variables using the copy to subclass approach

Avoiding global variables, most of the time

Summary

Questions

Further reading

Chapter 4: Methods and Their Arguments

Technical requirements

Understanding that there are no class methods, only instance methods

Naming methods

Special method names

Using the many types of method arguments

Positional arguments

Optional positional arguments

Rest arguments

Keyword arguments

Block arguments

Learning about the importance of method visibility

Fixing visibility mistakes

Handling delegation

Delegating to other objects

Summary

Questions

Chapter 5: Handling Errors

Technical requirements

Handling errors with return values

Handling errors with exceptions

Considering performance when using exceptions

Retrying transient errors

Understanding more advanced retrying

Breaking circuits

Designing exception class hierarchies

Using core exception classes

Summary

Questions

Chapter 6: Formatting Code for Easy Reading

Technical requirements

Recognizing different perspectives of code formatting

Learning how syntactic consistency affects maintainability

Enforcing consistency with RuboCop

Understanding the consequences of using arbitrary limits

Checking basic code formatting with Ruby

Realizing the actual importance of code formatting

Summary

Questions

Section 2: Ruby Library Programming Principles

Chapter 7: Designing Your Library

Technical requirements

Focusing on the user experience

Library naming

Library first impressions

The simplest possible interface

Determining the appropriate size for your library

Handling complexity trade-offs during method design

Fewer but more complex methods

Summary

Questions

Chapter 8: Designing for Extensibility

Technical requirements

Using Ruby's extensibility features

Designing plugin systems

Designing a basic plugin system

Handling changes to classes

Plugin modifications to classes

Supporting plugin dependencies

Making plugin loading easier

Handling subclasses in plugin systems

Configuring plugins

Understanding globally frozen, locally mutable design

Summary

Questions

Chapter 9: Metaprogramming and When to Use It

Technical requirements

Learning the pros and cons of abstraction

Eliminating redundancy

Understanding different ways of metaprogramming methods

Using method_missing judiciously

Summary

Questions

Chapter 10: Designing Useful Domain-Specific Languages

Technical requirements

Designing your DSL

Configuration DSLs

DSLs for making specific changes

DSLs for reducing the verbosity of code

Libraries implemented as DSLs

Implementing your DSL

Learning when to use a DSL

Summary

Questions

Chapter 11: Testing to Ensure Your Code Works

Technical requirements

Understanding why testing is so critical in Ruby

Learning different approaches to testing

Considering test complexity

Understanding the many levels of testing

Realizing that 100% coverage means nothing

Summary

Questions

Chapter 12: Handling Change

Technical requirements

Considering reasons to refactor

Learning about the refactoring process

Implementing the most common Ruby refactoring techniques

Extracting a method

Extracting a class

Refactoring to add features

Removing features properly

Removing methods

Removing constants

Summary

Questions

Chapter 13: Using Common Design Patterns

Technical requirements

Learning about the many design patterns that are built into Ruby

The object pool design pattern

The prototype design pattern

The private class data design pattern

The proxy design pattern

Handling cases where there can be only one

Dealing with nothing

Visiting objects

Adapting and strategizing

Summary

Questions

Chapter 14: Optimizing Your Library

Technical requirements

Understanding that you probably don't need to optimize code

Profiling first, optimizing second

Understanding that no code is faster than no code

Handling code where everything is slow

Summary

Questions

Section 3: Ruby Web Programming Principles

Chapter 15: The Database Is Key

Technical requirements

Learning why database design is so important

Deciding on a database to use

Understanding the most important database design principles

Considerations when denormalizing your database design

Other database design principles

Treating the database as not just dumb storage

Choosing the model layer

Handling database and model errors

Summary

Further reading

Questions

Chapter 16: Web Application Design Principles

Technical requirements

Choosing between client-side and server-side design

Deciding on a web framework

Ruby on Rails

Sinatra

Grape

Roda

Designing URL paths

Structuring with monoliths, microservices, and island chains

Summary

Questions

Chapter 17: Robust Web Application Security

Technical requirements

Understanding that most security issues in Ruby web applications are high level

Never trust input

Performing access control at the highest level possible

Avoiding injection

Script injection

SQL injection

Code injection

Approaching high-security environments

Limiting database access

Internal firewalling

Randomizing memory layouts

Limiting filesystem access

Limiting system call access

Summary

Questions

Assessments

Other Books You May Enjoy

Preface

The purpose of this book is to teach useful principles for intermediate to advanced Ruby programmers to follow. The focus is not generally on how to implement solutions, but on different implementation approaches, the trade-offs between them, and why some approaches are better in certain situations. While the main focus of the book is teaching principles, in some cases this book also teaches advanced Ruby programming techniques.

This book starts by teaching some fundamental principles, such as how best to use the core classes, when and how best to use each variable type, and how best to use the different types of method arguments. After building on the fundamental principles, the book teaches principles for better library design, such as how best to design extensible plugin systems, trade-offs when using metaprogramming and DSLs, and how best to approach testing, refactoring, and optimization. This book concludes with a few small chapters that are focused on principles specific to web programming in Ruby, with a separate chapter each on database design, application design, and web application security.

Who this book is for

The target audience for the book is intermediate to advanced Ruby programmers who are interested in learning principles to improve their Ruby programming.

What this book covers

Chapter 1, Getting the Most out of Core Classes, focuses on the optimal usage of the built-in classes.

Chapter 2, Designing Useful Custom Classes, focuses on when it makes sense to implement a custom class, applying SOLID design to custom classes, and the trade-offs between having large classes and having a large number of classes.

Chapter 3, Proper Variable Usage, focuses on how best to use each of Ruby's variable types.

Chapter 4, Methods and Their Arguments, focuses on method naming principles, the best usage of each of the method argument types, and choosing proper method visibility.

Chapter 5, Handling Errors, focuses on the trade-offs between using exceptions and return values for handling errors, handling transient errors, and designing exception class hierarchies.

Chapter 6, Formatting Code for Easy Reading, focuses on different viewpoints on the importance of syntactic complexity and the downsides of arbitrary limits.

Chapter 7, Designing Your Library, focuses on designing your library around the user experience and complexity trade-offs when designing methods for your library.

Chapter 8, Designing for Extensibility, focuses on designing useful plugin systems to allow for extensibility in libraries.

Chapter 9, Metaprogramming and When to Use It, focuses on the pros and cons of abstraction, avoiding redundancy, and trade-offs between the two approaches Ruby has for metaprogramming.

Chapter 10, Designing Useful Domain-Specific Languages, focuses on when and how best to design DSLs.

Chapter 11, Testing to Ensure Your Code Works, focuses on why testing is so important, how to approach testing and manage complexity during testing, and the importance of code coverage.

Chapter 12, Handling Change, focuses on when and how best to implement refactoring in libraries, and deprecation strategies.

Chapter 13, Using Common Design Patterns, focuses on principles for the best usage of five common design patterns.

Chapter 14, Optimizing Your Library, focuses on determining when optimization is needed and how to approach optimization if it is needed.

Chapter 15, The Database Is Key, focuses on why database design is so important in web programming, how best to use database features, and how best to handle database errors.

Chapter 16, Web Application Design Principles, focuses on trade-offs for different types of application design, different frameworks, and different URL designs.

Chapter 17, Robust Web Application Security, focuses on important web security techniques and how to approach designing web applications for high-security environments.

To get the most out of this book

This book assumes intermediate to advanced knowledge of the Ruby programming language. There are sections of the book that are accessible to those with only basic knowledge of Ruby, but most of the book assumes you already understand how Ruby works and tries to teach principles for more productive usage of Ruby.

While most of the ideas and principles discussed in the book, and most of the code examples used in the book, apply to any version of Ruby, some of the examples and principles are specific to Ruby 3.0, the latest release at the time of publication.

If you are using the digital version of this book, we advise you to type the code yourself or access the code via the GitHub repository (link available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.

Download the example code files

You can download the example code files for this book from GitHub at https://github.com/PacktPublishing/Polished-Ruby-Programming. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Conventions used

There are a number of text conventions used throughout this book.

Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "As an example of this, consider a SQL database library that needs to execute INSERT, UPDATE, and DELETE SQL queries to modify data."

A block of code is set as follows:

class Foo

  def self.bar

    :baz

  end

end

Any command-line input or output is written as follows:

# Warming up --------------------------------------

#   MultiplyProf    28.531k i/100ms

# Calculating -------------------------------------

#   MultiplyProf    284.095k (± 0.3%) i/s

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packt.com.

Section 1: Fundamental Ruby Programming Principles

The objective of this section is for you to understand the fundamental principles and trade-offs involved in Ruby programming, at the level of individual classes and methods.

This section comprises the following chapters:

Chapter 1, Getting the Most out of Core ClassesChapter 2, Designing Useful Custom ClassesChapter 3, Proper Variable UsageChapter 4, Methods and Their ArgumentsChapter 5, Handling ErrorsChapter 6,Formatting Code for Easy Reading