bless 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: 201fad31dea2baafb55c2ad7ece548a0326599fa
4
+ data.tar.gz: 68bb9c8af4be0781f1de984a4582f724ceb7dd25
5
+ SHA512:
6
+ metadata.gz: 94b932c692e91be83fb16eadbd3afec8ab38bd99faf14bf0fe1f97f85d70247d2da2420f89aad110edd74bf9bb1a8dfb85afef0bc0f59edbedbca10f1a0d5aa2
7
+ data.tar.gz: a49f5f6179cdfa9770fa8f2308e5eea7fb1062a2ff8cb73a49c36ba31b5c7a4bcd06ecaa4782f033dd62e45c542ba6256d4a1be1dba92f02f34706d9f6c64360
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - ruby-head
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,6 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ #watch('spec/spec_helper.rb') { 'spec' }
5
+ end
6
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Lennart Fridén
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ # Bliss [![Build Status](https://secure.travis-ci.org/DevL/bliss.png)](http://travis-ci.org/DevL/bliss) ![Gem version](https://badge.fury.io/rb/bliss.png)
2
+
3
+ Miss Perl? Ever wished Ruby was more like it? Me neither, but that's no excuse for going nuts and hack together some insane code that Perlifies Ruby.
4
+
5
+ There's no excuse for using it in production though.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'bliss'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install bliss
20
+
21
+ ## Usage
22
+
23
+ Using bless is simplicity itself. Or was it idiocy? Nevermind, bless your followers by uttering the following. Preferably followed by a prayer that your code will not be seen by anyone. Ever.
24
+
25
+ ```ruby
26
+ blessed_object = bless(Object.new, String)
27
+ blessed_object.instance_of?(String) # => true
28
+ ```
29
+
30
+ Now, the proverbial example usage of bless in Perl would operate in conjunction with the `my` keyword. However, implementing support for that proved to be somewhat less than straightforward. To make a long story short, setting a local variable from an eval AND retaining that local variable beyond the scope of the eval is simply not possible in Ruby\*.
31
+
32
+ \* Until we come up with the idea of hacking Rubinius into submission. Hopefully we'll never think of that.
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it
37
+ 2. Create your feature branch (`git checkout -b I-say-we-take-off-and-nuke-it-from-orbit`)
38
+ 3. Commit your changes (`git commit -am 'It is the only way to make sure!'`)
39
+ 4. Push to the branch (`git push origin I-say-we-take-off-and-nuke-it-from-orbit`)
40
+ 5. Create new Pull Request
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bless/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'bless'
8
+ spec.version = Bless::VERSION
9
+ spec.authors = ['Lennart Fridén', 'Kim Persson']
10
+ spec.email = ['lennart@devl.se']
11
+ spec.description = %q{Blessed are the Perl hackers}
12
+ spec.summary = %q{Brings the blessings of Perl to Ruby}
13
+ spec.homepage = 'https://github.com/DevL/bless'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'binding_of_caller', '~> 0.7'
22
+ spec.add_development_dependency 'byebug', '~> 2.5'
23
+ spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'rake', '~> 10'
25
+ spec.add_development_dependency 'rspec', '~> 2.14'
26
+ spec.add_development_dependency 'guard', '~> 2.2'
27
+ spec.add_development_dependency 'guard-rspec', '~> 4.2'
28
+ end
@@ -0,0 +1,123 @@
1
+ require 'bless/version'
2
+ require 'binding_of_caller'
3
+
4
+ module Bless
5
+ class Blesser
6
+ class CannotBlessSimpletons < StandardError; end
7
+
8
+ def self.bless(object, klass, context, invoker)
9
+ assert_kernel_ancestor_on(object)
10
+ new(object, klass, context, invoker).bless
11
+ end
12
+
13
+ def bless
14
+ if blessee_writeable?
15
+ convert_or_set_blessee_in_context
16
+ else
17
+ convert_or_instantiate
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :blessee, :blessee_code, :blessee_owner, :code, :context, :invoker, :klass, :object
24
+
25
+ def initialize(object, klass, context, invoker)
26
+ @object = object
27
+ @context = context
28
+ @invoker = invoker
29
+ @klass = determine_target_class(klass)
30
+ @code = code_for_invoker
31
+ @blessee_code = extract_blessee_code
32
+ @blessee, @blessee_owner = blessee_and_owner
33
+ end
34
+
35
+ def self.assert_kernel_ancestor_on(object)
36
+ object.class.ancestors.include?(Kernel)
37
+ rescue NoMethodError => e
38
+ raise CannotBlessSimpletons.new
39
+ end
40
+
41
+ def determine_target_class(klass)
42
+ klass || context.eval('self.class')
43
+ end
44
+
45
+ def code_for_invoker
46
+ file, line = invoker.split(':')
47
+ IO.readlines(file)[line.to_i - 1].strip
48
+ end
49
+
50
+ def extract_blessee_code
51
+ match_data = code.match code_regex
52
+ match_data[:var] if match_data
53
+ end
54
+
55
+ def code_regex
56
+ /
57
+ bless
58
+ (\(\s*|\s+) # optional opening parens followed by optional whitespace OR mandatory whitespace
59
+ (?<var>[^,\s]+) # extract variable name
60
+ (\s*,\s*.+)? # optional whitespace, comma, optional whitespace, whatever (all optional)
61
+ \)? # optional closing parens
62
+ /x
63
+ end
64
+
65
+ def blessee_and_owner
66
+ blessee_elements = blessee_code.split('.')
67
+ [blessee_elements.pop, blessee_elements.join('.')]
68
+ end
69
+
70
+ def convertable_object?
71
+ Kernel.methods.include?(klass.name.to_sym)
72
+ end
73
+
74
+ def convert_or_set_blessee_in_context
75
+ if convertable_object?
76
+ convert_blessee_in_context
77
+ else
78
+ set_blessee_in_context
79
+ end
80
+ end
81
+
82
+ def convert_blessee_in_context
83
+ context.eval("#{blessee_code} = send('#{klass.name}', #{blessee_code})")
84
+ end
85
+
86
+ def set_blessee_in_context
87
+ context.eval("#{blessee_code} = #{klass}.new")
88
+ end
89
+
90
+ def convert_or_instantiate
91
+ if convertable_object?
92
+ send(klass.name, object)
93
+ else
94
+ klass.new
95
+ end
96
+ end
97
+
98
+ def blessee_writeable?
99
+ if !blessee_owner.empty?
100
+ blessee_assignable?
101
+ else
102
+ assignable_variables_for_context.include?(blessee.to_sym)
103
+ end
104
+ end
105
+
106
+ def blessee_assignable?
107
+ context.eval "#{blessee_owner}.respond_to?('#{blessee}=')"
108
+ end
109
+
110
+ def assignable_variables_for_context
111
+ context.eval('local_variables + instance_variables')
112
+ end
113
+ end
114
+ end
115
+
116
+ module Kernel
117
+ def bless(object, klass = nil)
118
+ context = binding.of_caller(1)
119
+ invoker = caller.first
120
+
121
+ Bless::Blesser.bless(object, klass, context, invoker)
122
+ end
123
+ end
@@ -0,0 +1,3 @@
1
+ module Bless
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,82 @@
1
+ require 'bless'
2
+
3
+ class SomePackage
4
+ end
5
+
6
+ class ParentObject
7
+ attr_accessor :child
8
+ end
9
+
10
+ describe 'Kernel#bless' do
11
+ it 'can bless an object' do
12
+ expected_class = SomePackage
13
+ some_object = bless Object.new, expected_class
14
+ some_object.should be_an_instance_of(expected_class)
15
+ end
16
+
17
+ it 'can bless a nested object' do
18
+ expected_class = SomePackage
19
+ parent = ParentObject.new
20
+ parent.child = :unchanged_child_object
21
+ bless parent.child, expected_class
22
+ parent.child.should be_an_instance_of(expected_class)
23
+ end
24
+
25
+ it 'can bless an instance variable' do
26
+ expected_class = SomePackage
27
+ @some_instance_variable = :unchanged_instance_variable
28
+ bless @some_instance_variable, expected_class
29
+ @some_instance_variable.should be_an_instance_of(expected_class)
30
+ end
31
+
32
+ it 'defaults to the current class' do
33
+ some_object = bless Object.new
34
+ expected_class = self.class
35
+ # the matcher 'be_an_instance_of' uses the 'describe' description
36
+ some_object.instance_of?(expected_class).should be_true
37
+ end
38
+
39
+ it 'changes the reference to the object without requiring assignment' do
40
+ some_object = :unchanged_object
41
+ expected_class = SomePackage
42
+ bless some_object, expected_class
43
+
44
+ some_object.should be_an_instance_of(expected_class)
45
+ end
46
+
47
+ it 'changes the reference to the object when using an implicit class' do
48
+ some_object = String.new
49
+ expected_class = self.class
50
+ bless some_object
51
+
52
+ some_object.instance_of?(expected_class).should be_true
53
+ end
54
+
55
+ it 'attempts to convert the object if possible' do
56
+ some_object = 15
57
+ expected = [15]
58
+ bless some_object, Array
59
+
60
+ some_object.should == expected
61
+ end
62
+
63
+ it 'handles parens' do
64
+ some_object = { a: 1 }
65
+ expected = [[:a, 1]]
66
+ bless(some_object, Array)
67
+
68
+ some_object.should == expected
69
+ end
70
+
71
+ class VeryBasic < BasicObject
72
+ def bless_me(klass)
73
+ ::Kernel.bless self, klass
74
+ end
75
+ end
76
+
77
+ it 'gracefully handles BasicObjects' do
78
+ expect {
79
+ VeryBasic.new.bless_me(Hash)
80
+ }.to raise_error(Bless::Blesser::CannotBlessSimpletons)
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bless
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lennart Fridén
8
+ - Kim Persson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: binding_of_caller
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.7'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.7'
28
+ - !ruby/object:Gem::Dependency
29
+ name: byebug
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.5'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.5'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.3'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.3'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '2.14'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '2.14'
84
+ - !ruby/object:Gem::Dependency
85
+ name: guard
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '2.2'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '2.2'
98
+ - !ruby/object:Gem::Dependency
99
+ name: guard-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '4.2'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '4.2'
112
+ description: Blessed are the Perl hackers
113
+ email:
114
+ - lennart@devl.se
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - Guardfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - bless.gemspec
128
+ - lib/bless.rb
129
+ - lib/bless/version.rb
130
+ - spec/bless_spec.rb
131
+ homepage: https://github.com/DevL/bless
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.2.0
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Brings the blessings of Perl to Ruby
155
+ test_files:
156
+ - spec/bless_spec.rb