Skip to content

Cado-Labs/smart_engine

Repository files navigation

SmartCore::Engine · Supported by Cado Labs · Gem Version

Generic SmartCore functionality.


Supported by Cado Labs


Installation

gem 'smart_engine'
bundle install
# --- or ---
gem install smart_engine
require 'smart_core'

Technologies


Global set of error types

  • SmartCore::Error (inherited from ::StandardError);
  • SmartCore::ArgumentError (inherited from ::ArgumentError);
  • SmartCore::FrozenError (inherited from ::FrozenError);
  • SmartCore::NameError (inherited from ::NameError);
  • SmartCore::TypeError (inherited from ::TypeError);

Simple reentrant lock

lock = SmartCore::Engine::Lock.new
lock.synchronize { your_code }

Atomic thread-safe value container

atom = SmartCore::Engine::Atom.new # initial value - nil
atom.value # => nil
# --- or ---
atom = SmartCore::Engine::Atom.new(7) # initial value - 7
atom.value # => 7

# set new value (thread-safely)
atom.swap { |original_value| original_value * 2 }
atom.value # => 14

Any Object Frozener

  • works with any type of ruby objects (event with BasicObject);
  • uses classic Ruby C-level frozen?/freeze functionality;
# as a singleton

object = BasicObject.new
SmartCore::Engine::Frozener.frozen?(object) # => false

SmartCore::Engine::Frozener.freeze(object)
SmartCore::Engine::Frozener.frozen?(object) # => true
# as a mixin

class EmptyObject < BasicObject
  include SmartCore::Engine::Frozener::Mixin
end

object = EmptyObject.new

object.frozen? # => false
object.freeze
object.frozen? # => true

Basic Object Refinements

Ruby's BasicObject class does not have some fundamental (extremely important for instrumenting) methods:

  • is_a? / kind_of?
  • instance_of?
  • freeze / frozen?
  • hash
  • nil?

SmartCore::Ext::BasicObjectAsObject refinement solves this problem (by Ruby's internal API without any manualy-emulated behavior).

# without refinement:
basic_obj = ::BasicObject.new

basic_obj.is_a?(::BasicObject) # raises ::NoMethodError
basic_obj.kind_of?(::BasicObject) # raises ::NoMethodError
basic_obj.instance_of?(::BasicObject) # rasies ::NoMethodError
basic_obj.freeze # raises ::NoMethodError
basic_obj.frozen? # raises ::NoMethodError
basic_object.hash # raises ::NoMethodError
basic_object.nil? # raises ::NoMethodError
# with refinement:
using SmartCore::Ext::BasicObjectAsObject

basic_obj = ::BasicObject.new

basic_obj.is_a?(::BasicObject) # => true
basic_obj.kind_of?(::BasicObject) # => true
basic_obj.instance_of?(::BasicObject) # => true
basic_obj.instance_of?(::Object) # => false
basic_obj.is_a?(::Integer) # => false
basic_obj.kind_of?(::Integer) # => false

basic_obj.frozen? # => false
basic_obj.freeze # => self
basic_obj.frozen? # => true

basic_obj.nil? # => false

basic_obj.hash # => 2682859680348634421 (some Integer value)

Inline rescue pipe

  • works with an array of proc objects;
  • returns the result of the first non-failed proc;
  • provides an error interception interface (a block argument);
  • fails with the last failed proc exception (if all procs were failed and interceptor was not passed);

Return the result of the first non-failed proc

SmartCore::Engine::RescueExt.inline_rescue_pipe(
  -> { raise },
  -> { raise },
  -> { 123 },
  -> { 567 },
  -> { raise },
)
# => output: 123

Fail with the last failed proc exception

SmartCore::Engine::RescueExt.inline_rescue_pipe(
  -> { raise(::ArgumentError) },
  -> { raise(::TypeError) },
  -> { raise(::ZeroDivisionError) }
)
# => fails with ZeroDivisionError

Error interception

SmartCore::Engine::RescueExt.inline_rescue_pipe(
  -> { raise(::ArgumentError) },
  -> { raise(::TypeError) },
  -> { raise(::ZeroDivisionError, 'Intercepted exception') }
) do |error|
  error.message
end
# => output: "Intercepted exception"

Roadmap

  • migrate to Github Actions in CI;
  • thread-safety for BasicObject extensions;

Contributing

  • Fork it ( https://github.com/smart-rb/smart_engine )
  • Create your feature branch (git checkout -b feature/my-new-feature)
  • Commit your changes (git commit -am '[feature_context] Add some feature')
  • Push to the branch (git push origin feature/my-new-feature)
  • Create new Pull Request

License

Released under MIT License.

Supporting

Supported by Cado Labs

Authors

Rustam Ibragimov