Generic SmartCore functionality.
gem 'smart_engine'
bundle install
# --- or ---
gem install smart_engine
require 'smart_core'
- Global set of error types
- Simple reentrant lock
- Atomic thread-safe value container
- Any Object Frozener (classic c-level
frozen?
/freeze
) - Basic Object Refinements (
SmartCore::Ext::BasicObjectAsObject
) - Inline rescue pipe
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
);
lock = SmartCore::Engine::Lock.new
lock.synchronize { your_code }
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
- 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
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)
- 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);
SmartCore::Engine::RescueExt.inline_rescue_pipe(
-> { raise },
-> { raise },
-> { 123 },
-> { 567 },
-> { raise },
)
# => output: 123
SmartCore::Engine::RescueExt.inline_rescue_pipe(
-> { raise(::ArgumentError) },
-> { raise(::TypeError) },
-> { raise(::ZeroDivisionError) }
)
# => fails with ZeroDivisionError
SmartCore::Engine::RescueExt.inline_rescue_pipe(
-> { raise(::ArgumentError) },
-> { raise(::TypeError) },
-> { raise(::ZeroDivisionError, 'Intercepted exception') }
) do |error|
error.message
end
# => output: "Intercepted exception"
- migrate to Github Actions in CI;
- thread-safety for BasicObject extensions;
- 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
Released under MIT License.