PRISM is amazing and opens a new way to access metadata in Ruby. However:
- Loading and reloading the Abstract Syntax Tree (AST) multiple times is inefficient
- Higher level abstractions of the AST (classes, methods) are more useful
- Navigating the AST can be difficult
Lowkey provides a central API to make storing and accessing of the AST by multiple gems much easier.
It's the secret sauce behind LowType, LowLoad and Raindeer in general.
Lowkey.load(file_path: 'my_class.rb')
Lowkey['my_class.rb'] # => FileProxy
Lowkey['MyNamespace::MyClass'] # => ClassProxyProxies are a higher level of abstraction above the Abstract Syntax Tree, to allow easy access to basic metadata.
Proxy Types:
FileProxyClassProxyMethodProxy[UNRELEASED]ParamProxy[UNRELEASED]ReturnProxy[UNRELEASED]
Queries allow you to get nodes within the AST via simple keypath syntax:
Lowkey['MyNamespace::MyClass.my_method'] # => MethodDefNodeUsing the same keypath query syntax we can manipulate the AST:
method_proxy = MethodProxy.new(my_params)
Lowkey['MyNamespace::MyClass.my_method'] = method_proxyIn the above example we have replaced the existing method with our own, using MethodProxy to easily build a new method.
Export a manipulated entities to memory with:
Lowkey['my_class.rb'].export
Lowkey['MyNamespace::MyClass'].export
Lowkey['MyNamespace::MyClass.my_method'].exportSave manipulated entities to disk with:
Lowkey['my_class.rb'].save(file_path:) # Replaces entire file.
Lowkey['MyNamespace::MyClass'].save(file_path:) # Replaces part of a file.
Lowkey['MyNamespace::MyClass.my_method'].save(file_path:) # Replaces part of a file.Copy and paste the following and change the defaults to configure Lowkey:
# This configuration should be set before calling "Lowkey.load".
Lowkey.configure do |config|
# A big benefit of Lowkey is its caching of abstract syntax trees, file proxies and class proxies.
# But to save memory you should clear them after the "class load"/setup stage of your application.
# Set to "false" or call "Lowkey.clear" after you no longer need Lowkey, such as in a boot script.
config.cache = true
endAdd gem 'lowkey' to your Gemfile then:
bundle install