assignbot 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ef98faf3e37d5d3202cdb1a39a1296ba9be56601
4
+ data.tar.gz: 45e74d267458e6bed9abe74407eb24d505c7a8ae
5
+ SHA512:
6
+ metadata.gz: 4c385dea04056f779e1642ee4eefa2a61094ea385a111f0874f8b656550a6fc6bd0bde6b382a7974b4be5f68112bb908d90f307fc97488f65b750a263ab0de30
7
+ data.tar.gz: ca21b53b96d44d4e7bcdf218454f2ea56695c0ea183e1ad92fd53a607e8c0fa3cbc1a546718782bf93b76113a06897c30fde8afcc34572946f1a328c5208db0d
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ *.swp
12
+ *.swo
13
+ *.swn
14
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in assignbot.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Adam Pahlevi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # Assignbot
2
+
3
+ In Ruby, assigning variables can be tricky. Could you assign from new? Could you always guarantee that?
4
+
5
+ Assignbot guarantee you can assign from `.assign`, code changes to your codebase is not required
6
+ unless you want custom behaviour.
7
+
8
+ [ ![Codeship Status for saveav/assignbot](https://codeship.com/projects/78f58640-581d-0133-7dbd-1ebb29223a5a/status?branch=master)](https://codeship.com/projects/109613)
9
+
10
+ # Use cases
11
+
12
+ 1. Assign from the hash, from params
13
+ 2. Assign from the hash, from JSON
14
+
15
+ ## Installation
16
+
17
+ To install Assignbot, add this line to your Gemfile:
18
+
19
+ ```ruby
20
+ gem 'assignbot'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it system-wide by issuing:
28
+
29
+ $ gem install assignbot
30
+
31
+ ## Usage
32
+
33
+ Assume you have the following User class:
34
+
35
+ ```ruby
36
+ class User
37
+ attr_accessor :name, :age, :id
38
+ end
39
+ ```
40
+
41
+ Basic usage of assigner does not require significant code change to your model/ruby class, other than a one-liner include statement:
42
+
43
+ ```ruby
44
+ class User
45
+ include Assignbot
46
+
47
+ # your other ruby code
48
+ end
49
+ ```
50
+
51
+ By doing so, you already make User to be assignable from a Hash:
52
+
53
+ ```ruby
54
+ user_params = {
55
+ name: "Adam Pahlevi",
56
+ age: 23,
57
+ id: "934-2311"
58
+ }
59
+
60
+ user = User.new
61
+ user.assign(user_params)
62
+ user.name == "Adam Pahlevi" # returns true
63
+ ```
64
+
65
+ If you would like to explicitly tell Assignbot what are the assignable variables, then you have to define the variables explicitly:
66
+
67
+ ```ruby
68
+ class User
69
+ include Assignbot
70
+
71
+ assigner do
72
+ name from: :name
73
+ age from: :age
74
+ id from: :id
75
+ end
76
+ # your other ruby code
77
+ end
78
+ ```
79
+
80
+ Explicitly defining assigner also allow you to map the value from source variable, which have different nomenclature, to the target variable in your Ruby class.
81
+
82
+ ## License
83
+
84
+ The gem is proudly available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
85
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'assignbot/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'assignbot'
8
+ spec.version = Assignbot::VERSION
9
+ spec.authors = ['Adam Pahlevi']
10
+ spec.email = ['adam.pahlevi@gmail.com']
11
+
12
+ spec.summary = 'Automatical object assignment using hash'
13
+ spec.description = "Assign an object's instance variables using hash"
14
+ spec.homepage = 'https://github.com/saveav/assignbot'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.9'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.3'
25
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'assignbot'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,61 @@
1
+ require 'assignbot/version'
2
+ require 'assignbot/core'
3
+
4
+ require 'assignbot/dsl/assigner_dsl'
5
+
6
+ require 'assignbot/exceptions/unmasked_error'
7
+ require 'assignbot/exceptions/dsl_error'
8
+
9
+ require 'assignbot/foundations/assignable'
10
+ require 'assignbot/foundations/assigner'
11
+ require 'assignbot/foundations/variable'
12
+
13
+ module Assignbot
14
+ def self.included(base)
15
+ base.extend(Assignbot::ClassDsl)
16
+ end
17
+
18
+ def assignbot_assign(assigner_name, hash)
19
+ assignable = Assignbot::Core.get_assignable(self.class)
20
+ assigner = assignable.get_assigner(assigner_name)
21
+ fail AssigningError, "Undefined assigner scope: #{assigner_name}" unless assigner_name.to_sym == :default
22
+
23
+ if assigner && assigner.variables.any?
24
+ # use explicitly from defined variables
25
+ assigner.variables.each do |_, variable_ic|
26
+ source_variable = variable_ic.source_variable
27
+ value = hash[source_variable.to_s] || hash[source_variable.to_sym]
28
+ send(variable_ic.receptor, value)
29
+ end
30
+ else
31
+ hash.each do |target_variable, value|
32
+ send(:"#{target_variable}=", value)
33
+ end
34
+ end
35
+ end
36
+ private :assignbot_assign
37
+
38
+ def assign(hash)
39
+ assignbot_assign(:default, hash)
40
+ end
41
+
42
+ def method_missing(name, *args, &block)
43
+ if name =~ /assign_/i
44
+ assigner_name = name.to_s.gsub(/^assign_/i, '')
45
+ assignbot_assign(assigner_name, args[0])
46
+ else
47
+ super(name, *args, &block)
48
+ end
49
+ end
50
+
51
+ # inner class that get extended to the base class
52
+ module ClassDsl
53
+
54
+ module_function
55
+
56
+ def assigner(&block)
57
+ assigner_dsl = AssignerDsl.new(self)
58
+ assigner_dsl.instance_eval(&block)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ module Assignbot
2
+ # Store Assignbot-wide static variables and functions
3
+ module Core
4
+ ASSIGNABLES = {}
5
+
6
+ module_function
7
+
8
+ def get_assignable(target_class)
9
+ fail DslError, 'Pass in class' unless target_class.is_a?(Class)
10
+ target_class_name = target_class.to_s
11
+
12
+ asclass = ASSIGNABLES[target_class_name]
13
+ if asclass.nil?
14
+ asclass = Assignable.new(target_class)
15
+ ASSIGNABLES[target_class_name] = asclass
16
+ end
17
+ asclass
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Assignbot
2
+ # DSL class that will be instantiated on call of "assigner"
3
+ class AssignerDsl
4
+ attr_reader :target_class
5
+
6
+ def initialize(target_class)
7
+ @target_class = target_class
8
+ # assignable instance
9
+ @assignable_ic = Core.get_assignable(target_class)
10
+ end
11
+
12
+ def set(target_variable, source_variable, receptor)
13
+ @assignable_ic.add_variable(:default,
14
+ target_variable,
15
+ source_variable,
16
+ receptor)
17
+ end
18
+
19
+ def method_missing(name, *args)
20
+ params = args[0]
21
+ fail DslError, 'Put in hash as an argument!' unless params.is_a?(Hash)
22
+
23
+ source_variable = params[:from] || params['from']
24
+ set(name, source_variable, :"#{source_variable}=")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ module Assignbot
2
+ class AssigningError < UnmaskedError
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Assignbot
2
+ class DslError < UnmaskedError
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Assignbot
2
+ # error that does not need to be masked as other error
3
+ class UnmaskedError < StandardError
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ module Assignbot
2
+ # assignable represent the class, it has many assigner
3
+ class Assignable
4
+ # all instances of assigners, type: Hash
5
+ attr_reader :assigners
6
+ # the target class of it
7
+ attr_reader :target_class
8
+
9
+ def initialize(target_class)
10
+ @target_class = target_class
11
+ @assigners = {}
12
+ end
13
+
14
+ def add_assigner(assigner)
15
+ assigner_name = Assigner.canonify_name(assigner.name)
16
+ assigners[assigner_name] = assigner
17
+ nil
18
+ end
19
+
20
+ def get_assigner(assigner_name)
21
+ assigner = assigners[Assigner.canonify_name(assigner_name)]
22
+ assigner
23
+ end
24
+
25
+ def add_variable(assigner_name,
26
+ target_variable,
27
+ source_variable,
28
+ receptor)
29
+
30
+ # create one instance of Assigner unless defined
31
+ assigner = get_assigner(assigner_name)
32
+ if assigner.nil?
33
+ assigner = Assigner.new(self, assigner_name)
34
+ add_assigner(assigner)
35
+ end
36
+
37
+ variable = Variable.new(assigner)
38
+ variable.target_variable = target_variable
39
+ variable.source_variable = source_variable
40
+ variable.receptor = receptor
41
+ assigner.add_variable(variable)
42
+
43
+ nil
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ module Assignbot
2
+ # assignable has many assigner, the default
3
+ # assigner is named :default. one can design assigner from
4
+ # params which is from JSON, or from XML. if unnamed,
5
+ # then use :default as name
6
+ class Assigner
7
+ attr_reader :assignable
8
+ attr_reader :name
9
+ # all variables, based on target_variable
10
+ attr_reader :variables
11
+
12
+ def self.canonify_name(name)
13
+ unless name.is_a?(String) || name.is_a?(Symbol)
14
+ fail DslError, "Name must be either symbol or string, got: #{name}"
15
+ end
16
+ name.to_s.downcase.tr(' ', '_').to_sym
17
+ end
18
+
19
+ def initialize(assignable, assigner_name)
20
+ @assignable = assignable
21
+ @name = assigner_name
22
+ @variables = {}
23
+ end
24
+
25
+ def get_variable(target_variable)
26
+ @variables[target_variable]
27
+ end
28
+
29
+ def add_variable(variable)
30
+ @variables[variable.target_variable] = variable
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ module Assignbot
2
+ # represent the variable both from target, and from source; and through which
3
+ # method the value from source can be copied to target
4
+ class Variable
5
+ attr_reader :assigner
6
+
7
+ # the variable to which the value will be copied to
8
+ attr_accessor :target_variable
9
+ attr_accessor :source_variable
10
+
11
+ # receptor, receive value
12
+ attr_accessor :receptor
13
+
14
+ def initialize(assigner)
15
+ @assigner = assigner
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ # our Assignbot gem
2
+ module Assignbot
3
+ VERSION = '0.1.0'
4
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: assignbot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Pahlevi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ description: Assign an object's instance variables using hash
56
+ email:
57
+ - adam.pahlevi@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - CODE_OF_CONDUCT.md
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - assignbot.gemspec
71
+ - bin/console
72
+ - bin/setup
73
+ - lib/assignbot.rb
74
+ - lib/assignbot/core.rb
75
+ - lib/assignbot/dsl/assigner_dsl.rb
76
+ - lib/assignbot/exceptions/assigning_error.rb
77
+ - lib/assignbot/exceptions/dsl_error.rb
78
+ - lib/assignbot/exceptions/unmasked_error.rb
79
+ - lib/assignbot/foundations/assignable.rb
80
+ - lib/assignbot/foundations/assigner.rb
81
+ - lib/assignbot/foundations/variable.rb
82
+ - lib/assignbot/version.rb
83
+ homepage: https://github.com/saveav/assignbot
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.4.5
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Automatical object assignment using hash
107
+ test_files: []
108
+ has_rdoc: