| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A simple and convenient way to declare complex constructors with a support for various commonly used type systems. (in active development).
gem 'smart_initializer'bundle install
# --- or ---
gem install smart_initializerrequire 'smart_core/initializer'NOTE!: SmarteCore::Initializer's constructor is invoked first in order to guarantee the validity of the SmartCore::Initializer's functionality (such as attribute overlap chek, instant type checking, value post-processing by finalize, etc)
NOTE: :finalize block are not invoked on omitted optional: true attributes which has no :default definition bock and which are not passed to the constructor. Example:
# without :default
class User
include SmartCore::Initializer
option :age, :string, optional: true, finalize: -> (val) { "#{val}_years" }
end
User.new.age # => nil# with :default
class User
include SmartCore::Initializer
option :age, :string, optional: true, default: '0', finalize: -> (val) { "#{val}_years" }
end
User.new.age # => '0_years'NOTE: last Hash argument will be treated as kwargs;
param <attribute_name>,
<type=SmartCore::Types::Value::Any>, # Any by default
cast: false, # false by default
privacy: :public, # :public by default
finalize: proc { |value| value }, # no finalization by default
finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
as: :some_alias, # define attribute alias
mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
type_system: :smart_types # used by defaultparams <atribute_name1>, <attribute_name2>, <attribute_name3>, ...,
mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
privacy: :private # incapsulate all attributes as privateoption <attribute_name>,
<type=SmartCore::Types::Value::Any>, # Any by default
cast: false, # false by default
privacy: :public, # :public by default
finalize: proc { |value| value }, # no finalization by default
finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
default: 123, # no default value by default
default: proc { 123 }, # use proc/lambda object for dynamic initialization
as: :some_alias, # define attribute alias
mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
optional: true # (false by default) mark attribute as optional (attribute will be defined with `nil` or by `default:` value)
type_system: :smart_types # used by defaultoptions <attribute_name1>, <attribute_name2>, <attribute_name3>, ...,
mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
privacy: :private # incapsulate all attributes as private# with pre-configured type system (:smart_types, see Configuration doc)
class MyStructure
include SmartCore::Initializer
end# with manually chosen settings
class MyStructure
include SmartCore::Initializer(
type_system: :smart_types, # use smart_types
auto_cast: true, # type-cast all values by default
strict_options: false # ignore extra kwargs passed to the constructor
)
end
class AnotherStructure
include SmartCore::Initializer(type_system: :thy_types) # use thy_types and global defaults
endclass User
include SmartCore::Initializer
# --- or ---
include SmartCore::Initializer(type_system: :smart_types)
param :user_id, SmartCore::Types::Value::Integer, cast: false, privacy: :public
param :login, :string, mutable: true
option :role, default: :user, finalize: -> { |value| Role.find(name: value) }
# NOTE: for method-based finalizetion use `your_method(value)` isntance method of your class;
# NOTE: for dynamic default values use `proc` objects and `lambda` objects;
params :name, :password
options :metadata, :enabled
end
# with correct types (incorrect types will raise SmartCore::Initializer::IncorrectTypeError)
object = User.new(1, 'kek123', 'John', 'test123', role: :admin, metadata: {}, enabled: false)
# attribute accessing:
object.user_id # => 1
object.login # => 'kek123'
object.name # => 'John'
object.password # => 'test123'
object.role # => :admin
object.metadata # => {}
object.enabled # => false
# attribute mutation (only mutable attributes have a mutator):
object.login = 123 # => (type vlaidation error) raises SmartCore::Initializer::IncorrectTypeError (expected String, got Integer)
object.login # => 'kek123'
object.login = 'pek456'
object.login # => 'pek456'class User
include SmartCore::Initializer
param :first_name, 'string'
param :second_name, 'string'
option :age, 'numeric'
option :is_admin, 'boolean', default: true
end
user = User.new('Rustam', 'Ibragimov', age: 28)
user.__params__ # => { first_name: 'Rustam', second_name: 'Ibragimov' }
user.__options__ # => { age: 28, is_admin: true }
user.__attributes__ # => { first_name: 'Rustam', second_name: 'Ibragimov', age: 28, is_admin: true }# Global configuration:
SmartCore::Initializer::Configuration.configure do |config|
config.default_type_system = :smart_types # default setting value
config.strict_options = true # default setting value
config.auto_cast = false # default setting value
end# Read configs:
SmartCore::Initializer::Configuration[:default_type_system]
SmartCore::Initializer::Configuration.config[:default_type_system]
SmartCore::Initializer::Configuration.config.settings.default_type_system# per-class configuration:
class Parameters
include SmartCore::Initializer(auto_cast: true, strict_options: false)
# 1. use globally configured `smart_types` (default value)
# 2. type-cast all attributes by default (auto_cast: true)
# 3. ignore extra kwarg-attributes passed to the constructor (strict_options: false)
end
class User
include SmartCore::Initializer(type_system: :thy_types)
# 1. use :thy_types isntead of pre-configured :smart_types
# 2. use pre-configured auto_cast (false by default above)
# 3. use pre-configured strict_options ()
end# debug class-related configurations:
class SomeClass
include SmartCore::Initializer(type_system: :thy_types)
end
SomeClass.__initializer_settings__[:type_system] # => :thy_types
SomeClass.__initializer_settings__[:auto_cast] # => false
SomeClass.__initializer_settings__[:strict_options] # => true# for smart_types:
SmartCore::Initializer::TypeSystem::SmartTypes.type_alias('hsh', SmartCore::Types::Value::Hash)
# for thy:
SmartCore::Initializer::TypeSystem::ThyTypes.type_alias('int', Thy::Tyhes::Integer)
class User
include SmartCore::Initializer
param :data, 'hsh' # use your new defined type alias
option :metadata, :hsh # use your new defined type alias
param :age, 'int', type_system: :thy_types
end# for smart_types:
SmartCore::Initializer::TypeSystem::SmartTypes.type_aliases
# for thy_types:
SmartCore::Initializer::TypeSystem::ThyTypes.type_aliasesclass Order
include SmartCore::Initializer
param :manager, 'string' # cast: false is used by default
param :amount, 'float', cast: true
option :status, :symbol # cast: false is used by default
option :is_processed, 'boolean', cast: true
option :processed_at, 'time', cast: true
end
order = Order.new(
'Daiver',
'123.456',
status: :pending,
is_processed: nil,
processed_at: '2021-01-01'
)
order.manager # => 'Daiver'
order.amount # => 123.456 (type casted)
order.status # => :pending
order.is_processed # => false (type casted)
order.processed_at # => 2021-01-01 00:00:00 +0300 (type casted)# per class
class User
include SmartCore::Initializer(auto_cast: true) # auto type cast every attribute
param :x, 'string'
param :y, 'numeric', cast: false # disable type-casting
option :b, 'integer', cast: false # disable type-casting
option :c, 'boolean'
end# globally
SmartCore::Initializer::Configuration.configure do |config|
config.auto_cast = true # false by default
endclass User
include SmartCore::Initializer
option :name, :name
option :age, :integer
ext_init { |instance| instance.define_singleton_method(:extra) { :ext1 } }
ext_init { |instance| instance.define_singleton_method(:extra2) { :ext2 } }
end
user = User.new(name: 'keka', age: 123)
user.name # => 'keka'
user.age # => 123
user.extra # => :ext1
user.extra2 # => :ext2Support for Thy::Types type system (gem)
gem 'thy'bundle installrequire 'thy'
SmartCore::Initializer::Configuration.plugin(:thy_types)class User
include SmartCore::Initializer(type_system: :thy_types)
param :nickname, 'string'
param :email, 'value.text', type_system: :smart_types # mixing with smart_types
option :admin, Thy::Types::Boolean, default: false
option :age, (Thy::Type.new { |value| value > 18 }) # custom thy type is supported too
end
# valid case:
User.new('daiver', 'iamdaiver@gmail.com', { admin: true, age: 19 })
# => new user object
# invalid case (invalid age)
User.new('daiver', 'iamdaiver@gmail.com', { age: 17 })
# SmartCore::Initializer::ThyTypeValidationError
# invaldi case (invalid nickname)
User.new(123, 'test', { admin: true, age: 22 })
# => SmartCore::Initializer::ThyTypeValidationErrorbin/rspec -wbin/rspec -nbin/rspec -hbundle exec rake rubocopbundle exec rake rubocop -AReleased under MIT License.
| Back | FazBrowse Home | New Git URL |