https://github.com/jeremyevans/ruby-refrigerator Skip to content Navigation Menu Toggle navigation Sign in * Product + GitHub Copilot Write better code with AI + Security Find and fix vulnerabilities + Actions Automate any workflow + Codespaces Instant dev environments + Issues Plan and track work + Code Review Manage code changes + Discussions Collaborate outside of code + Code Search Find more, search less Explore + All features + Documentation + GitHub Skills + Blog * Solutions By company size + Enterprises + Small and medium teams + Startups By use case + DevSecOps + DevOps + CI/CD + View all use cases By industry + Healthcare + Financial services + Manufacturing + Government + View all industries View all solutions * Resources Topics + AI + DevOps + Security + Software Development + View all Explore + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners + Executive Insights * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Enterprise + Enterprise platform AI-powered developer platform Available add-ons + Advanced Security Enterprise-grade security features + GitHub Copilot Enterprise-grade AI features + Premium Support Enterprise-grade 24/7 support * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up Reseting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} jeremyevans / ruby-refrigerator Public * Notifications You must be signed in to change notification settings * Fork 6 * Star 249 Freeze all core ruby classes 249 stars 6 forks Branches Tags Activity Star Notifications You must be signed in to change notification settings * Code * Issues 0 * Pull requests 0 * Discussions * Actions * Security * Insights Additional navigation options * Code * Issues * Pull requests * Discussions * Actions * Security * Insights jeremyevans/ruby-refrigerator master BranchesTags [ ] Go to file Code Folders and files Name Name Last commit Last commit message date Latest commit History 74 Commits .github/workflows .github/workflows bin bin lib lib module_names module_names test test .ci.gemfile .ci.gemfile .gitignore .gitignore CHANGELOG CHANGELOG MIT-LICENSE MIT-LICENSE README.rdoc README.rdoc Rakefile Rakefile gen_module_names.rb gen_module_names.rb refrigerator.gemspec refrigerator.gemspec View all files Repository files navigation * README * License RefrigeratorP | 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. InstallationP | gem install refrigerator Source CodeP | Source code is available on GitHub at github.com/jeremyevans/ ruby-refrigerator UsageP | freeze_coreP | 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_requireP | 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_requireP | 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 `
' 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 `': can't modify frozen # (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 `
' 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 `' 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 # (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 `' 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 versionsP | 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 ModulesP | Internal, deprecated, and private classes and modules are not frozen by refrigerator. LicenseP | MIT AuthorP | Jeremy Evans About Freeze all core ruby classes Resources Readme Activity Stars 249 stars Watchers 10 watching Forks 6 forks Report repository Releases 11 tags Packages 0 No packages published Contributors 2 * @jeremyevans jeremyevans Jeremy Evans * @PikachuEXE PikachuEXE PikachuEXE Languages * Ruby 100.0% Footer (c) 2024 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.