34
loading...
This website collects cookies to deliver better user experience
Note: This is an updated version of a previous unfinished Medium series of mine you can find here.
class Document
attr_accessor :title, :author, :content
def initialize(title, author, content)
@title = title
@author = author
@content = content
end
def words
@content.split
end
def word_count
words.size
end
end
“The thing to note about the code above is that it follows the Ruby indentation convention: In Ruby you indent your code with two spaces per level” — Eloquent Ruby Ch 1
“…so idiomatic Ruby should be serenely tab free” — Eloquent Ruby Ch 1
“The real questions regarding comments are when and how much” — Eloquent Ruby Ch 1
# Class that models a plain text document, complete with title
# and author:
#
# doc = Document.new('Hamlet', 'Shakespeare', 'To be or...')
# puts doc.title
# puts doc.author
# puts doc.content
#
# Document instances know how to parse their content into words:
#
# puts doc.words
# puts doc.word_count
As an aside, it’s rare to see spaces before or after parens in Ruby code in the wild, as mentioned in the Ruby Style Guide
Document.new( 'Hamlet', 'Shakespeare', 'To be or...' )Document.new('Hamlet', 'Shakespeare', 'To be or...')
# Class that models a plain text document, complete with title
# and author.
#
# @example
#
# doc = Document.new('Hamlet', 'Shakespeare', 'To be or...')
# puts doc.title
# puts doc.author
# puts doc.content
#
# @author Russ
#
class Document
# Title of the document
attr_accessor :title
# Author of the document
attr_accessor :author
# Content of the document
attr_accessor :content
# Creates a new instance of a Document
#
# @param title [String]
# Title of the Document
#
# @param author [String]
# Author of the Document
#
# @param content [String]
# The content of the Document
#
# @return [Document]
def initialize(title, author, content)
@title = title
@author = author
@content = content
end
# Gets the individual words from our content
#
# @return [Array[String]]
def words
@content.split
end
# Gets the count of words in the document
#
# @return [Integer]
def word_count
words.size
end
end
# Using ngram analysis, compute the probability
# that this document and the one passed in were
# written by the same person, This algorithm is
# known to be valid for American English and will
# probably work for British and Canadian English.
#
def same_author_probability(other_document)
# Implementation left as an exercise for the reader...
end
@see
tag to point to something like Wikipedia or another resource for further reading:# @see https://en.wikipedia.org/wiki/N-gram N-Grams on Wikipedia
return 0 if divisor == 0 # Avoid division by zero
count += 1 # Add one to count
# Divides two numbers
#
# @param a [Number]
# @param b [Number]
#
# @return [Number]
# Result of dividing two numbers
#
# @return [0]
# Zero is returned if the divisor is zero, to prevent divide
# by zero errors.
“The danger in comments that explain how the code works is that they can easily slide off into the worst reason for adding comments: to make a badly written program somewhat comprehensible.” — Eloquent Ruby Ch 1
class FunDocument
ANTLERS_PER_MALE_MOOSE = 2
lowercase_words_separated_by_underscore
CamelCase
and SCREAMING_SNAKE_CASE
, but over the past few years Rubyists have moved towards the latter as was Russ’s preference in the book.def find_document(title, author)
def words
@content.split
end
words
if (condition) # Bad
if condition # Good
puts "text"
describe "An RSpec test" do
# ...
end
puts
isn’t single arity:puts "Some", "words"
;
to put quite a few things on one line. Absent code golfing and shell one-liners, this should be avoided except in a few cases as mentioned by the book:class DocumentException < Exception; end
def method_to_be_overridden; end
def add(a, b) a + b end
add
:def add(a, b) = a + b
def set_something(a) = something = a
{}
or do .. end
. As far as which one to use, that’s still quite the argument.10.times { |n| puts "The number is #{n}" }
10.times do |n|
puts "The number is #{n}"
puts "Twice the number is #{n * 2}"
end
do
syntax should be used with multi-liners.do
s are used for ones that have a primary purpose of side effects and output like so:[1,2,3].map { |v|
v * 2
}
[1, 2, 3].each do |v|
puts v
end
“More than anything else, code that looks like Ruby looks readable.” — Eloquent Ruby Ch 1
doc.words.each do |word|
puts word
end
doc.words.each { |word| puts word }
puts *doc.words
do
notation:doc.words.each { |word| some_really_really_long_expression(with, lots, of, args).that(does_even_more(things)) }
“And thirdly, the code is more what you’d call “guidelines” than actual rules.” — Barbossa
puts doc.author
doc.instance_of?(Document)
puts doc.instance_of? self.class.superclass.class
is_a?
to be used as a shorter version of instance_of?
.Set
in the book. A more recent set of libraries with good documentation I’d take a look into are ones like:Kernel
methods like Float
which break the rules, but are used as stand-ins for class names:# Works something like this:
module Kernel
def Float(v) = Float.new(v)
end
pi = Float('3.14159')
origin = Point[0, 0]
class Point
def self.[](x, y)
new(x, y)
end
def initialize(x, y)
@x = x
@y = y
end
end
“Above all else, pragmatism: You cannot make readable code by blindly following some rules.” — Eloquent Ruby Ch 1