Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to configure gem #3

Merged
merged 3 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
ez_attributes (0.2.2)
ez_attributes (0.3.0)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -93,4 +93,4 @@ DEPENDENCIES
yard

BUNDLED WITH
2.2.25
2.2.29
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ user.name
# => "Matz"
```

### Configuration
You can disable getters
```ruby
class User
extend EzAttributes.configure(getters: false)

attributes :name, :age, email: 'guest@user.com'
end

u = User.new(name: 'Matz', age: 22)
# => #<User:0x000055bac152f130 @name="Matz", @age=22, @email="guest@user.com">

u.name
# NoMethodError (undefined method `name' for #<User:0x000055bac152f130>)

```

## Development

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.
Expand Down
24 changes: 19 additions & 5 deletions lib/ez_attributes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative 'ez_attributes/config'

# Easily define initializers with keyword args.
# It supports required and optional args.
#
Expand All @@ -14,8 +16,17 @@
# User.new(name: 'Matheus', age: 22)
# => #<User:0x000055bac152f130 @name="Matheus", @age=22, @email="guest@user.com">
module EzAttributes
class << self
attr_accessor :config

# Defines config
def configure(**opts)
@config = Config.new(**opts)
self
end
end
# Gem version
VERSION = "0.2.2"
VERSION = '0.3.0'

# Attributes that won't have a getter to prevent conflicts with default methods
EXCEPTIONS = [:class].freeze
Expand All @@ -24,19 +35,22 @@ module EzAttributes
def attributes(*args, **args_with_default)
required_args = args.map { |name| "#{name}:" }
optional_args = args_with_default.map { |name, _| "#{name}: __args_with_default[:#{name}]" }
init_args = (required_args + optional_args).join(", ")
init_args = (required_args + optional_args).join(', ')

define_method("__args_with_default", -> { Marshal.load(Marshal.dump(args_with_default)) })
define_method('__args_with_default', -> { Marshal.load(Marshal.dump(args_with_default)) })
private :__args_with_default

all_args = args + args_with_default.keys
attr_reader(*(all_args - EXCEPTIONS))
config = EzAttributes.config
attr_reader(*(all_args - EXCEPTIONS)) if config&.getters || config.nil?

class_eval <<~RUBY, __FILE__, __LINE__ + 1
def initialize(#{init_args})
#{all_args.map { |name| "@#{name} = binding.local_variable_get(:#{name})" }.join("; ")}
#{all_args.map { |name| "@#{name} = binding.local_variable_get(:#{name})" }.join('; ')}
end
RUBY
# Reset config
EzAttributes.config = Config.new
m3xq marked this conversation as resolved.
Show resolved Hide resolved
end

# Defines a single keyword argument for a class initializer
Expand Down
22 changes: 22 additions & 0 deletions lib/ez_attributes/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module EzAttributes
# Config for EzAttributes
# @example
# class User
# extend EzAttributes.configure(getters: false)
#
# attributes :name, :age
# end
#
# user = User.new(name: 'Matz', age: 22)
# p user.name
# => `<main>': undefined method `name' for #<User:0x000055a07f700f60 @name="Matz", @age=22> (NoMethodError)
class Config
attr_reader :getters

def initialize(getters: true)
@getters = getters
end
end
end
54 changes: 48 additions & 6 deletions spec/ez_attributes_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@

it "requires keyword args" do
expect { single_arg_class.new(1) }.to raise_error(
ArgumentError,
/wrong number of arguments \(given 1, expected 0; required keyword: :?a\)/
)
ArgumentError,
/wrong number of arguments \(given 1, expected 0; required keyword: :?a\)/
)
end
end

Expand Down Expand Up @@ -64,9 +64,9 @@

it "requires keyword args" do
expect { multiple_arg_class.new(1, 2) }.to raise_error(
ArgumentError,
/wrong number of arguments \(given 2, expected 0; required keywords: a, b\)/
)
ArgumentError,
/wrong number of arguments \(given 2, expected 0; required keywords: a, b\)/
)
end
end

Expand Down Expand Up @@ -137,4 +137,46 @@ def change_attr
expect(obj2.a).to eq [1]
end
end

context "when config is not present" do
let(:test_class) do
Class.new do
extend EzAttributes

attributes :test
end
end

it "defines getters" do
expect { test_class.new(test: "test").test }.not_to raise_error
end
end

context "when config is present and has getters: true" do
let(:test_class) do
Class.new do
extend EzAttributes.configure(getters: true)

attributes :test
end
end

it "defines getters" do
expect { test_class.new(test: "test").test }.not_to raise_error
end
end

context "when config is present and has getters: false" do
let(:test_class) do
Class.new do
extend EzAttributes.configure(getters: false)

attributes :test
end
end

it "does not define getters" do
expect { test_class.new(test: "test").test }.to raise_error NoMethodError
end
end
end