class BibleBot::Verse

Verse represents a single verse in the bible.

Attributes

book[R]
chapter_number[R]
verse_number[R]

Public Class Methods

from_id(id) click to toggle source

Turns an Inteter into a Verse For more details, see note above the `id` method.

@param id [Integer] @return [Verse] @example

Verse.from_id(19_105_001) #=> <Verse book="Psalms" chapter_number=105 verse_number=1>
# File lib/bible_bot/verse.rb, line 17
def self.from_id(id)
  return from_string_id(id) if id.is_a?(String)
  return nil if id.nil?
  raise BibleBot::InvalidVerseError unless id.is_a?(Integer)

  book_id        = id / 1_000_000
  chapter_number = id / 1_000 % 1_000
  verse_number   = id % 1_000
  book           = BibleBot::Book.find_by_id(book_id)

  new(book: book, chapter_number: chapter_number, verse_number: verse_number)
end
new(book:, chapter_number:, verse_number:) click to toggle source

@param book [Book] @param chapter_number [Integer] @param verse_number [Integer]

# File lib/bible_bot/verse.rb, line 33
def initialize(book:, chapter_number:,  verse_number:)
  @book = book
  @chapter_number = chapter_number
  @verse_number = verse_number
end

Private Class Methods

from_string_id(string_id) click to toggle source

This gets called by {from_id} to allow it to be backwards compatible for a while. @deprecated Use {from_id} instead. @param verse_id [String] ex: “genesis-001-001” @return [Verse] ex: <Verse book=“Genesis” chapter_number=1 verse_number=1>

# File lib/bible_bot/verse.rb, line 145
def self.from_string_id(string_id)
  parts = string_id.split( '-' )

  book_name      = parts[0].gsub( '_', ' ' )
  chapter_number = parts[1].to_i
  verse_number   = parts[2].to_i

  book = BibleBot::Bible.books.select{ |b| b.name.downcase == book_name }.first

  new(book: book, chapter_number: chapter_number, verse_number: verse_number)
end

Public Instance Methods

<=>(other) click to toggle source

The Comparable mixin uses this to define all the other comparable methods

@param other [Verse] @return [Integer] Either -1, 0, or 1

* -1: this verse is less than the other verse
* 0: this verse is equal to the other verse
* 1: this verse is greater than the other verse
# File lib/bible_bot/verse.rb, line 70
def <=>(other)
  id <=> other.id
end
formatted(include_book: true, include_chapter: true, include_chapter_on_single_chapter_books: false, include_verse: true) click to toggle source

@param include_book [Boolean] @param include_chapter [Boolean] @param include_chapter_on_single_chapter_books [Boolean] @param include_verse [Boolean] @return [String] @example

verse.formatted #=> "Genesis 5:23"
# File lib/bible_bot/verse.rb, line 81
def formatted(include_book: true, include_chapter: true, include_chapter_on_single_chapter_books: false, include_verse: true)
  str = String.new # Using String.new because string literals will be frozen in Ruby 3.0
  str << "#{book.formatted_name} " if include_book

  if book.single_chapter? && include_chapter_on_single_chapter_books == false
    str << "#{verse_number}" if include_verse
  else
    str << "#{chapter_number}" if include_chapter
    str << ":" if include_chapter && include_verse
    str << "#{verse_number}" if include_verse
  end

  str.strip.freeze
end
id() click to toggle source

Returns an Integer in the from of

|- book.id
|   |- chapter_number
|   |   |- verse_number
XX_XXX_XXX

Storing as an Integer makes it super convenient to store in a database and compare verses and verse ranges using simple database queries

@return [Integer] @example

verse.id #=> 19_105_001
              #-> this represents "Psalm 105:1"
# File lib/bible_bot/verse.rb, line 53
def id
  @id ||= "#{book.id}#{chapter_number.to_s.rjust(3, '0')}#{verse_number.to_s.rjust(3, '0')}".to_i
end
inspect() click to toggle source

@return [Hash]

# File lib/bible_bot/verse.rb, line 119
def inspect
  {
    book: book&.name,
    chapter_number: chapter_number,
    verse_number: verse_number
  }
end
last_chapter_in_book?() click to toggle source

@return [Boolean]

# File lib/bible_bot/verse.rb, line 114
def last_chapter_in_book?
  chapter_number == book.chapters.length
end
last_verse_in_chapter?() click to toggle source

@return [Boolean]

# File lib/bible_bot/verse.rb, line 109
def last_verse_in_chapter?
  verse_number == book.chapters[chapter_number - 1]
end
next_verse() click to toggle source

Returns next verse. It will reach into the next chapter or the next book until it gets to the last verse in the bible, at which point it will return nil.

@return [Verse, nil]

# File lib/bible_bot/verse.rb, line 101
def next_verse
  return Verse.new(book: book, chapter_number: chapter_number, verse_number: verse_number + 1) unless last_verse_in_chapter?
  return Verse.new(book: book, chapter_number: chapter_number + 1, verse_number: 1) unless last_chapter_in_book?
  return Verse.new(book: book.next_book, chapter_number: 1, verse_number: 1) if book.next_book
  nil
end
string_id() click to toggle source

@deprecated Use {id} instead @return [String] ex: “psalms-023-001”

# File lib/bible_bot/verse.rb, line 59
def string_id
  "#{book.name.downcase.gsub(' ', '_')}-#{chapter_number.to_s.rjust(3, '0')}-#{verse_number.to_s.rjust(3, '0')}"
end
valid?() click to toggle source

@return [Boolean]

# File lib/bible_bot/verse.rb, line 128
def valid?
  book.is_a?(BibleBot::Book) &&
  chapter_number.is_a?(Integer) && chapter_number >= 1 && chapter_number <= book.chapters.length &&
  verse_number.is_a?(Integer) && verse_number >= 1 && verse_number <= book.chapters[chapter_number-1]
end
validate!() click to toggle source

Raises error if reference is invalid

# File lib/bible_bot/verse.rb, line 135
def validate!
  raise InvalidVerseError.new "Verse is not valid: #{inspect}" unless valid?
end