When you require
the aws-sdk-s3
library, which is part of the aws-sdk-s3
Gem, the library, in turn, require
s the aws-sdk-core
library:
# frozen_string_literal: true
# WARNING ABOUT GENERATED CODE
#
# This file is generated. See the contributing guide for more information:
# https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
#
# WARNING ABOUT GENERATED CODE
require 'aws-sdk-kms'
require 'aws-sigv4'
require 'aws-sdk-core'
#↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
The aws-sdk-core
library, which is part of the aws-sdk-core
Gem, in turn, loads the param_converter
library using Kernel#require_relative
, as you can see here:
# client modules
require_relative 'aws-sdk-core/client_stubs'
require_relative 'aws-sdk-core/async_client_stubs'
require_relative 'aws-sdk-core/eager_loader'
require_relative 'aws-sdk-core/errors'
require_relative 'aws-sdk-core/pageable_response'
require_relative 'aws-sdk-core/pager'
require_relative 'aws-sdk-core/param_converter'
#↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
The param_converter
library then, in turn, loads the date
library:
# frozen_string_literal: true
require 'stringio'
require 'date'
#↑↑↑↑↑↑↑↑↑↑↑↑↑
The aws-sdk-core
Gem does not depend on the date
Gem:
> spec.add_dependency('jmespath', '~> 1', '>= 1.6.1') # necessary for secure jmespath JSON parsing
> spec.add_dependency('aws-partitions', '~> 1', '>= 1.651.0') # necessary for new endpoint resolution
> spec.add_dependency('aws-sigv4', '~> 1.5') # necessary for making Aws::STS, SSO, SSOOIDC API calls
> spec.add_dependency('aws-eventstream', '~> 1', '>= 1.0.2') # necessary for binary eventstream
But you don't have to depend on the date
Gem in order to use the date
library, because the date
Gem is a default Gem, which means it is part of Ruby's standard library, gets maintained by the Ruby developers, doesn't need to be installed, doesn't need to be listed as a Gem dependency, and doesn't need to be activated.
So, that's why you don't have to require
the date
library yourself: because you require
a library, which in turn require
s another library, which in turn require_relative
s another library, which in turn require
s the date
library.
But the more interesting question is, should you require
the date
library? And the answer is, Yes, you should. Relying on a require
chain like this is extremely brittle: what if some library somewhere in the middle down this chain decides to change its internal structure and, e.g. validate dates using a different library or implement date validation themselves? Then your code breaks for no apparent reason.
The rule that I generally follow is that every script must stand on its own, i.e. every script must require
all of its dependencies.
Now, in larger applications, this might get annoying, and might even lead to high startup latencies. A good example would be framework or a DSL, where it is simply expected that the framework or the DSL provides a set of libraries for you that are already pre-loaded. Imagine, you had to require
every active_support
library, active_model
library, active_relation
library, etc. you are using in a Ruby on Rails application. That would be stupid: if you write a Ruby on Rails model, you know that active_model
is loaded, you don't need to load it again.
So, a slightly relaxed rule is: every script that is intended to be require
d or executed by a client must stand on its own. Scripts that are internal to the application may rely on internal knowledge about which libraries are already required
.