00:00:03.879
I'm happy to take part in my presentation at RubyConf Australia. Today's topic is the journey of the Ruby standard library.
00:00:11.200
We will explore Ruby's standard libraries and core packages.
00:00:18.119
To start, let me introduce myself.
00:00:25.400
I'm Hiroshi Shibata. Please call me Hiroshi.
00:00:31.359
I am an open-source software developer at Anath.
00:00:37.160
I am a proud member of the Ruby core team and the RubyGems and Bundler teams.
00:00:43.719
My work involves developing and maintaining the Ruby programming language and the Ruby ecosystem.
00:00:49.399
Thank you for using Ruby and writing Ruby code every day.
00:00:54.800
I traveled from Japan to present at RubyConf Australia today.
00:01:00.840
As you may know, Japan is the birthplace of the Ruby language, so I'm happy to be here today.
00:01:07.799
Let me introduce my company, Anath, which provides a platform for the construction industry.
00:01:15.479
Our services are built using Ruby and Rails.
00:01:21.280
In Japan, our construction industry has a market size of over 1.5 billion Australian dollars.
00:01:30.880
We need to develop products more quickly using Ruby and Rails.
00:01:37.119
Anath strongly supports the Ruby ecosystem.
00:01:42.200
Now, let's begin by introducing the first topic: the history of standard libraries.
00:01:48.520
First, we need to look at how `require` works in Ruby.
00:01:54.200
This involves classifying Ruby classes and libraries.
00:02:00.439
For immediate classes like `Time`, `String`, or `Hash`, we do not need to require them.
00:02:06.640
However, standard libraries require you to call the `require` method.
00:02:13.879
We can categorize libraries into Pure Ruby libraries and C extensions.
00:02:20.120
You may need to require C libraries for external libraries provided by different distributions.
00:02:27.959
The `require` method is the most famous way to load additional Ruby code into your Ruby context.
00:02:34.160
If you wish to use RSS, it can be easily loaded using a simple `require` statement.
00:02:40.159
The `require` method returns `true` if successful; if not, it raises a LoadError.
00:02:46.519
Ruby will search for your library in the load path, including your Ruby installation paths.
00:02:53.599
The `require` keyword can also load C extensions.
00:03:00.560
On Linux or macOS, it loads extensions depending on the platform.
00:03:07.560
Lastly, we have `require_relative`, which only looks in the current directory.
00:03:12.640
This explains how Ruby manages its own standard libraries.
00:03:18.920
As of Ruby 1.8, there were over 13 libraries available.
00:03:25.599
However, Ruby 3.3, released on Christmas Day 2023, saw that number decrease to around 185.
00:03:35.560
Today, I will introduce RubyGems.
00:03:41.280
How do Ruby code and core packages differ?
00:03:49.240
In many programming languages, we don't need to write generic algorithms and data structures, thanks to standard libraries.
00:03:58.320
Unfortunately, Ruby has Ruby Application Archive (RAA), which isn't available today.
00:04:04.560
This is a web archive where Ruby programmers could upload their Ruby code.
00:04:10.560
You can download these archives and extract them to install Ruby extensions.
00:04:16.960
To use libraries from RAA, you need to run a Ruby script named `setup.rb` for installation.
00:04:24.639
The `setup.rb` script installs the libraries into the same directory as your Ruby installation.
00:04:31.799
You will often need to run the command as a superuser, or root account.
00:04:37.440
Ruby f is an alternative for RAA, specifically for Ruby libraries.
00:04:44.000
It includes metadata like dependencies, names, and versions.
00:04:50.680
RAA lacks this metadata mechanism.
00:04:59.360
RubyGems has released around 400 G files.
00:05:05.280
Matz decided to make RubyGems the default package manager for Ruby starting with Ruby 1.9.
00:05:11.520
This was a significant decision for us.
00:05:19.760
The first version of RubyGems was released in 2004, which means this year marks its 20th anniversary.
00:05:27.440
After Ruby 1.9, GitHub provided a Gem repository called gems.github.com in the past.
00:05:34.080
However, it closed on March 29, five years ago.
00:05:50.800
RubyC and RubyGems migrated to rubygems.org by 2013 and 2014.
00:05:58.480
Since then, rubygems.org has become our main Ruby library repository.
00:06:04.480
Today, RubyGems can install many gems from rubygems.org.
00:06:11.960
We need to know about Gem specifications in RubyGems.
00:06:18.319
Gem specifications can be accessed using the `gem` command in IRB at any time.
00:06:25.360
For instance, to view the gem specification of a specific gem, you can use IRB.
00:06:31.960
Ruby Gems extend the original Ruby `require` to load gems using their specifications.
00:06:38.680
Unlike the original Ruby `require`, RubyGems can add gem paths even when they don't exist in the load path.
00:06:47.440
This extended `require` is slower than Ruby's original `require` because it searches all installed gems.
00:06:54.320
For example, it takes considerably longer to load a specific gem in the local environment.
00:07:02.240
To optimize performance, we should avoid loading RubyGems automatically.
00:07:09.200
The Bundler provides the capability of dependency resolution via a Gemfile.
00:07:16.720
You should specify Gem sources in your Gemfile to use private gem servers.
00:07:23.160
Then, you can specify gem names along with version requirements.
00:07:30.360
The `Bundler` generates a Gemfile.lock file that lists all dependencies.
00:07:36.960
It includes details like architecture and OS version.
00:07:44.080
Dependency resolution in Bundler allows for consistent environments.
00:07:51.680
However, RubyGems doesn't support locking within a Ruby process.
00:07:58.960
Bundler ensures necessary gems are available during application runtime.
00:08:05.440
Now, let's discuss how the dependency resolution engine works.
00:08:11.840
Bundler employs a resolution engine called PGraph since version 2.4.
00:08:19.200
This version allows for faster resolutions compared to the older Marin engine.
00:08:27.440
The PGraph code works even in simple dependency cases.
00:08:34.560
For example, if you have gems with dependencies, you will declare them in your Gemfile.
00:08:41.760
Bundler uses this information for resolution.
00:08:49.680
You pass this source definition to an instance of the `PGraph` class for building the resolution.
00:08:56.240
Finally, the `solve` method can be called for the resolution result.
00:09:03.919
This process can illustrate selection cases involving gem versions.
00:09:10.440
Consider a case where versions attempt to resolve successfully.
00:09:17.200
If a specified version is present, it will return that as a solution.
00:09:23.680
If conflicts arise, the process will raise a failure exception.
00:09:30.240
We will explore a second more complex example now.
00:09:37.680
When you have multiple versions of gems, dependency resolution gets trickier.
00:09:43.440
This may lead to situations where dependencies cannot be satisfied simultaneously.
00:09:50.240
Consider approaching this process with the understanding of PGraph output.
00:09:56.840
To ensure robust dependency resolution, consider the interdependencies of your gems.
00:10:04.000
If a specific dependency cannot be matched, you may receive dependency errors.
00:10:10.240
In this process, an example where a gem with conflicting dependencies might break.
00:10:19.200
It's vital to define your constraints carefully to avoid resolution failures.
00:10:26.480
A deeper investigation may expose dependency problems that have been overlooked.
00:10:32.480
The key to avoiding issues arises through understanding your gem's relationships.
00:10:40.000
To explore further, we need to look at the evolution of PGraph.
00:10:47.800
With each RubyGems version, there's been progress in library management.
00:10:54.320
Now let's further analyze the investigation performed by Bundler.
00:11:01.720
Bundler provides methods to manage gems and their versions within applications.
00:11:08.480
Let’s clarify the core difference between Ruby standard libraries and RubyGems.
00:11:15.360
Standard libraries are bundled with Ruby; RubyGems operate independently and must be managed.
00:11:22.960
Each mechanism allows for a robust ecosystem that developers can leverage.
00:11:30.240
As I mentioned, the performance impact of extended `require` warrants thought.
00:11:37.760
While it's essential, one must balance performance with functionality when making decisions.
00:11:43.760
In the future, as Ruby evolves, expect enhancements to both RubyGems and Bundler.
00:11:50.320
There’s a strong focus on community engagement and expanding the contributors.
00:11:57.520
Collaborative efforts on open source projects continue to be a goal for Ruby.
00:12:04.640
With these strategies, we can build a more robust framework moving forward.
00:12:11.360
Our ultimate goal remains to enhance the user experience with Ruby.
00:12:17.680
Thank you for your attention as we move forward.
00:12:24.440
Remember to prepare for the challenges ahead.
00:12:31.840
The journey for Ruby will be an exciting one filled with opportunities.
00:12:39.760
Now, I will introduce some of the exciting features in the latest release.
00:12:46.360
An evolution of Ruby's standard library awaits us as we enter the future.
00:12:53.200
We have plans to improve functionality and security across libraries.
00:13:01.200
This focus aligns with our commitment to the community’s needs.
00:13:08.480
Your feedback has been invaluable in shaping these changes.
00:13:15.520
I hope you enjoyed today's discussion.
00:13:22.720
We're gearing up for Ruby 3.4 with exciting features and enhancements.
00:13:30.040
Our dedication to Ruby remains unwavering as we engage with the community.
00:13:37.920
My goal is to develop Ruby into the best programming language for everyone.
00:13:45.120
In conclusion, I appreciate your time and support for Ruby.
00:13:52.400
Thank you for being part of this journey.