Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file lib/constrainable
. To experiment with that code, run bin/console
for an interactive prompt.
TODO: Delete this and the text above, and describe your gem
Add this line to your application's Gemfile:
gem 'constrainable'
And then execute:
$ bundle
Or install it yourself as:
$ gem install constrainable
TODO: Write usage instructions here
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/erniebrodeur/constrainable.
module Constrainable
# def constrain(*args); end
# generate a 'named' method as part of the dsl (to supply required_keyword below).
# attach that method to Constrainable
# by including Constrainable (or Constrainable::ClassMethods or whatever) you will end up with a new
# method called required_keyword
module_function
def required_keyword(binding: binding, arguments: arguments)
raise 'AbstractClass'
end
end
# abstract
class Constraint
def generate_named_method
end
def call(binding: nil, arguments: nil)
end
end
# actual
class RequiredKeyword < Constraint
def method_name
:required_keyword # get this automagically (in the future)
end
def call(binding: nil, arguments: nil)
# figure out how to pass the binding
# dig and find the local bit from the binding.
raise ArgumentError, "#{keyword} was not supplied" unless value
end
class Constrained
include Constrainable
@constraints = {
RequiredArgument => %i[keyword two three]
}
# later on
constraints.each {|c, arguments| c.call(binding: binding, arguments: arguments) }
# begin
# constrain :some_method, :arg1, kind_of: String, required: true
# constrain :some_method, :arg2, kind_of: String, required: true
# constrain :some_method, :two, kind_of: String, required: true
# constrain :some_method, :three, kind_of: String, required: true
# end
# by :required_keywords, :some_method, kind_of: %i[keyword two three]
# by :user_signed_in, :some_method, user: user
# Constrainable.by_require_keywords :some_method, %i[keyword two three]
# Constrainable.by_kind_of :some_method, %i[keyword two three], [String, nil]
# by_user_signed_in :some_method, user
# by_require_keywords %i[keyword two three]
# by_kind_of [String, nil], %i[keyword two three]
# by_kind_of Array, %i[arg1 arg2]
# this call will supply the binding and the method_name (since it's in scope).
module Constrainable
# def constrain(*args); end
# generate a 'named' method as part of the dsl (to supply required_keyword below).
# attach that method to Constrainable
# by including Constrainable (or Constrainable::ClassMethods or whatever) you will end up with a new
# method called required_keyword
module_function
def required_keyword(binding: binding, arguments: arguments)
raise 'AbstractClass'
end
end
# abstract
class Constraint
def generate_named_method
end
def call(binding: nil, arguments: nil)
end
end
class RequiredKeyword < Constraint
def method_name
:required_keyword # get this automagically (in the future)
end
def call(binding: nil, arguments: nil)
# figure out how to pass the binding
# dig and find the local bit from the binding.
raise ArgumentError, "#{keyword} was not supplied" unless value
end
class A
include Constrainable
@constraints = {
RequiredArgument => %i[keyword two three]
}
# later on
constraints.each {|c, arguments| c.call(binding: binding, arguments: arguments) }
# begin
# constrain :some_method, :arg1, kind_of: String, required: true
# constrain :some_method, :arg2, kind_of: String, required: true
# constrain :some_method, :two, kind_of: String, required: true
# constrain :some_method, :three, kind_of: String, required: true
# end
# by :required_keywords, :some_method, kind_of: %i[keyword two three]
# by :user_signed_in, :some_method, user: user
# Constrainable.by_require_keywords :some_method, %i[keyword two three]
# Constrainable.by_kind_of :some_method, %i[keyword two three], [String, nil]
# by_user_signed_in :some_method, user
# by_require_keywords %i[keyword two three]
# by_kind_of [String, nil], %i[keyword two three]
# by_kind_of Array, %i[arg1 arg2]
# this call will supply the binding and the method_name (since it's in scope).
def some_method(arg1, arg2, keyword: nil, two: nil, three: nil)
raise ArgumentError, 'keyword must be present' unless keyword
raise ArgumentError, 'two must be present' unless two
raise ArgumentError, 'three must be present' unless three
# -> factors to this
[keyword, two, three].each { |v| raise ArgumentError, "#{v} must be present" unless v }
# -> factors to this
required_keyword %i[keyword two three]
puts arg1, arg2, keyword, two, three
end
end
putting it outside the method (somewhere in the class) brings us to a factor of one, but zero
additional lines
constrain :method, by_required_keywords(%i[keyword two three])
constrain_method :some_method, by(:required_keywords, %i[keyword two three])
def some_method(arg1, arg2, keyword: nil, two: nil, three: nil)
puts arg1, arg2, keyword, two, three
end
module Constrainable
module By
def call(*args)
end
end
end
module Constrainable
module By
module UserSignedIn
module_function
def wrapper(method, *args)
puts 'blow_up' unless args.any?
send method, args
end
end
end
end
def some_method(arg1, arg2, keyword: nil, two: nil, three: nil)
raise ArgumentError, 'keyword must be present' unless keyword
raise ArgumentError, 'two must be present' unless two
raise ArgumentError, 'three must be present' unless three
# -> factors to this
[keyword, two, three].each { |v| raise ArgumentError, "#{v} must be present" unless v }
# -> factors to this
required_keyword %i[keyword two three]
puts arg1, arg2, keyword, two, three
end
# putting it outside the method (somewhere in the class) brings us to a factor of one, but zero
# additional lines
constrain :method, by: { required_keywords: %i[keyword two three] }
constrain_class by: { signed_in: true }
def some_method(arg1, arg2, keyword: nil, two: nil, three: nil)
puts arg1, arg2, keyword, two, three
end
end
module Constrainable
module By
def call(*args)
end
end
end
module Constrainable
module By
module UserSignedIn
module_function
def wrapper(method, *args)
puts 'blow_up' unless args.any?
send method, args
end
end
end
end