I'm trying to create my first ruby gem. I've created the gem skeleton by using bundler bundle gem csv-probe
. Since the gem is intended as an extension of the csv
gem I used a hyphen in its name instead of the underscore as suggested in: https://guides.rubygems.org/name-your-gem/ .
I built the gem and tried to use it, however, when I try to load the gem via require 'csv-probe'
I get following error:
<internal:/usr/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- csv-probe (LoadError)
from <internal:/usr/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from ./test.rb:6:in `<main>'
I think it has something to do with the nested structure of the lib directory which bundler created.
lib
└── csv
├── probe
│ ├── checks.rb
│ └── version.rb
└── probe.rb
Maybe I extended the csv classes the wrong way?
Content of the lib/csv/probe.rb
file
# frozen_string_literal: true
require "csv"
require "terminal-table"
require_relative "probe/version"
require_relative "probe/checks"
# Probe provides methods for linting a:
# * CSV::Table
# * CSV::Row
#
# The linting methods:
# * lint_rows takes following arguments
# * csv_rows: CSV::Table
# * checks: Array of Probe Checks and
# * options
# * lint_row takes following arguments
# * csv_row: CSV::Row
# * checks: Array of Probe Checks and
# * optsions
module Probe
def self.lint_rows(csv_rows, checks, opts = {})
lineno_start = opts[:headers] ? 2 : 1
csv_rows.each.with_index(lineno_start) do |row, lineno|
opts[:lineno] = lineno
lint_row(row, checks, opts)
end
end
def self.lint_row(csv_row, checks, opts = {})
unless csv_row.is_a? CSV::Row
raise Error "lint_row(csv_row,...), csv_row is not of type CSV::Row, but of type '#{csv_row.class}'"
end
checks.each do |check|
check.evaluate(csv_row, opts)
rescue LintingError => e
raise e unless opts[:exception] == false
puts e.message # if exception oppressed, write error out on stdout
end
end
end
# Extend CSV::Table with .lint(...) method
class CSV::Table # rubocop:disable Style/ClassAndModuleChildren -> TODO: don't know how to fix this
def lint(checks, opts = {})
opts[:headers] = true unless opts.key?(:headers) # CSV::Table has always headers, hence set :headers = true
Probe.lint_rows(self, checks, opts)
end
end
# Extend CSV::Row with .lint(...) method
class CSV::Row # rubocop:disable Style/ClassAndModuleChildren
def lint(checks, opts = {})
Probe.lint_row(self, checks, opts)
end
end
I noticed when loading the gem by using require 'csv/probe'
it works, however, the generated README.md skeleton mentioned the gem is loaded via require 'csv-probe'
so I guess I did something wrong.
The source code for the gem can be found here:
https://gitlab.com/homebase-dev/csv-probe
As the error message says, Ruby cannot find a file named csv-probe.rb
.
Computers are very good at finding things. So, in 99% of all cases when a computer tells you it cannot find a thing, the reason is that the thing you told it to find does not exist.
So, step #1 would be to check: does the file named csv-probe.rb
actually exist?
In 99% of the rest of the cases, the thing you told the computer to find does actually exist somewhere , but it doesn't exist where you told the computer to look, in other words, you told the computer to look for the right thing in the wrong place.
So, in case the file does exist somewhere , step #2 would be to check: is the path where the file lives in Ruby's $LOAD_PATH
?
Note that RubyGems actually monkey-patches Kernel#require
and will automatically try and add a Gem's lib
directory to the $LOAD_PATH
. So, if the file exists inside some Gem's lib
directory, but is not currently in the $LOAD_PATH
, then the next step would be to investigate why that Gem's directory is not automatically added to the $LOAD_PATH
.
There is a convention that a Gem's main entry point should have the same name as the Gem, but that is only a convention. One of the most famous Gems that does not follow the convention is the activesupport
Gem whose main entry point is active_support.rb
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.