Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

refrigerator

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

refrigerator

  • 1.7.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

= Refrigerator

Refrigerator offers an easy way to freeze all ruby core classes and modules. It's designed to be used in production and when testing to make sure that no code is making unexpected changes to core classes or modules at runtime.

= Installation

gem install refrigerator

= Source Code

Source code is available on GitHub at https://github.com/jeremyevans/ruby-refrigerator

= Usage

== freeze_core

After loading all of the code for your application, you can call the +freeze_core+ method to freeze all core classes:

require 'refrigerator' Refrigerator.freeze_core

This will freeze all core classes, so that modifications to them at runtime will raise exceptions.

In a rack-based application, a good place to call freeze_core is at the end of the config.ru file.

You can also pass an :except option to +freeze_core+ with an array of class names not to freeze:

Refrigerator.freeze_core(:except=>['BasicObject'])

One reason to exclude certain classes is because you know they will be modified at runtime.

== check_require

Refrigerator also offers a +check_require+ method for checking libraries for modifications to the core classes. It allows you to easily see what fails when when you try to require the library with a frozen core, and offers some options that you can use to try to get the require to not raise an exception. This allows you to see what changes the library makes to the core classes. Here's an example of basic use:

Refrigerator.check_require('open3', :modules=>[:Open3])

The +check_require+ method takes the following options:

:modules :: Define the given module names before freezing the core (array of symbols) :classes :: Define the given class names before freezing the core (array of symbols or two element arrays with class name symbol and superclass name symbol) :exclude :: Exclude the given class/module names from freezing (array of strings) :depends :: Any dependencies to require before freezing the core (array of strings)

Without any options, +check_require+ will likely raise an exception, as it freezes the core before requiring, and if the required files tries to add a class or module to the global namespace, that will fail. The :modules and :classes options exist so that you can predefine the class so that the required file will reopen the existing class instead of defining a new class.

The :depends option can be easily used to load all dependencies of the required file before freezing the core. This is also necessary in most cases, especially when using the stdlib, since many stdlib files modify the core classes in ways beyond adding modules or classes. The :exclude option is basically a last resort, where you can disable the freezing of certain core classes, if you know the required library modifies them.

Here's an example using Sequel, a ruby database toolkit:

Refrigerator.check_require 'sequel', :depends=>%w'bigdecimal date thread time uri', :modules=>[:Sequel]

And an example using Roda, a ruby web toolkit:

Refrigerator.check_require 'roda', :depends=>%w'rack uri fileutils set tmpdir tempfile thread date time', :classes=>[:Roda]

Note that many stdlib libraries will fail +check_require+ unless you use the :exclude option, for example, +date+:

Refrigerator.check_require 'date', :classes=>[:Date, [:DateTime, :Date]]

Fails due to Time#to_date addition

Refrigerator.check_require 'date', :classes=>[:Date, [:DateTime, :Date]], :exclude=>['Time']

=> true

=== bin/check_require

refrigerator ships with a +check_require+ binary that offers access to +Refrigerator.check_require+ from the command line. Here's the usage:

$ bin/check_require Usage: check_require [options] path

Options: -m, --modules [Module1,Module2] define given modules under Object before freezing core classes -c [Class1,Class2/SuperclassOfClass2], --classes define given classes under Object before freezing core classes -r, --require [foo,bar/baz] require given libraries before freezing core classes -e, --exclude [Object,Array] exclude given core classes from freezing -h, -?, --help Show this message

You can use this to easily check ruby libraries for issues when requiring. For example, let's try with +open3+:

$ bin/check_require open3 Traceback (most recent call last): 4: from bin/check_require:42:in <main>' 3: from /home/billg/ruby-refrigerator/lib/refrigerator.rb:35:in check_require' 2: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' 1: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' /usr/local/lib/ruby/2.5/open3.rb:32:in `<top (required)>': can't modify frozen #Class:Object (FrozenError) $ bin/check_require -m Open3 open3

As displayed above, open3 does not modify any core classes, beyond defining the +Open3+ module.

Let's try with +date+:

$ bin/check_require date Traceback (most recent call last): 6: from bin/check_require:42:in <main>' 5: from /home/billg/ruby-refrigerator/lib/refrigerator.rb:35:in check_require' 4: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' 3: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' 2: from /usr/local/lib/ruby/2.5/date.rb:4:in <top (required)>' 1: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require': can't modify frozen #<Class:Object> (FrozenError) $ bin/check_require -c Date,DateTime/Date date Traceback (most recent call last): 6: from bin/check_require:42:in

' 5: from /home/billg/ruby-refrigerator/lib/refrigerator.rb:35:in check_require' 4: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' 3: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' 2: from /usr/local/lib/ruby/2.5/date.rb:4:in <top (required)>' 1: from /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require' /usr/local/lib/ruby/2.5/rubygems/core_ext/kernel_require.rb:59:in require': can't modify frozen class (FrozenError) $ bin/check_require -c Date,DateTime/Date -e Time date

The first failure is because +date+ defines the +Date+ and +DateTime+ classes, so you must define those classes first, using a slash to separate DateTime from the superclass Date. Note that it still fails in that case, but it doesn't even tell you why. It turns out the reason is that +date+ also adds +to_date+ and other methods to +Time+, so you need to exclude the freezing of +Time+ as well.

Here are a couple more examples, using Sequel and Roda:

bin/check_require -m Sequel -r bigdecimal,date,thread,time,uri sequel bin/check_require -c Roda -r rack,uri,fileutils,set,tmpdir,tempfile,thread,date,time roda

== Supporting new ruby minor versions

The list of constants that +freeze_core+ will freeze are stored in the module_names/*.txt files in the repository, with separate files per ruby minor version. When new ruby minor versions are released, the +module_names+ rake task can be run with the new ruby minor version, and it will generate the appropriate file.

== Skipped Classes and Modules

Internal, deprecated, and private classes and modules are not frozen by refrigerator.

= License

MIT

= Author

Jeremy Evans code@jeremyevans.net

FAQs

Package last updated on 28 Dec 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc