drain 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +6 -2
- data/.travis.yml +10 -0
- data/.yardopts +6 -1
- data/Gemfile +7 -0
- data/LICENSE.txt +1 -1
- data/README.md +11 -5
- data/Rakefile +7 -12
- data/drain.gemspec +15 -5
- data/gemspec.yml +4 -3
- data/lib/dr.rb +1 -0
- data/lib/{drain → dr}/base.rb +0 -0
- data/lib/{drain → dr}/base/bool.rb +0 -0
- data/lib/dr/base/converter.rb +33 -0
- data/lib/{drain → dr}/base/encoding.rb +0 -0
- data/lib/dr/base/eruby.rb +284 -0
- data/lib/{drain → dr}/base/functional.rb +2 -2
- data/lib/dr/base/graph.rb +378 -0
- data/lib/dr/base/utils.rb +28 -0
- data/lib/dr/parse.rb +1 -0
- data/lib/dr/parse/simple_parser.rb +70 -0
- data/lib/{drain → dr}/parse/time_parse.rb +0 -0
- data/lib/dr/ruby_ext.rb +1 -0
- data/lib/dr/ruby_ext/core_ext.rb +7 -0
- data/lib/{drain/ruby_ext/core_ext.rb → dr/ruby_ext/core_modules.rb} +67 -27
- data/lib/{drain → dr}/ruby_ext/meta_ext.rb +57 -30
- data/lib/dr/tools.rb +1 -0
- data/lib/{drain → dr}/tools/gtk.rb +0 -0
- data/lib/dr/version.rb +4 -0
- data/lib/drain.rb +2 -1
- data/test/helper.rb +12 -1
- data/test/test_converter.rb +42 -0
- data/test/test_core_ext.rb +116 -0
- data/test/test_graph.rb +126 -0
- data/test/test_meta.rb +65 -0
- data/test/test_simple_parser.rb +41 -0
- metadata +45 -21
- data/.document +0 -3
- data/lib/drain/base/eruby.rb +0 -28
- data/lib/drain/base/graph.rb +0 -213
- data/lib/drain/parse.rb +0 -5
- data/lib/drain/parse/simple_parser.rb +0 -61
- data/lib/drain/ruby_ext.rb +0 -5
- data/lib/drain/tools.rb +0 -5
- data/lib/drain/tools/git.rb +0 -116
- data/lib/drain/version.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2a6165b74687b54296ee9b273eac4465746de73b9774eb5466fd550031897cba
|
4
|
+
data.tar.gz: 915728a74d0050b45fec8167e51e2b08c3657defb5fc3187b25b4aca2ff18fb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1c013bdb8158298fec2a204063d142a328840e9f3bea214036932ddc59f696aca94549190df72b95b3110dbea295f7a2e240bd69dbb3ed7264911a201517297
|
7
|
+
data.tar.gz: 4cdffbe87293046d6752bd64a0e7e17224b16786d39cb5ff4f4537a5ed3da6722060acf44475774c4bc788f4b09abbb66cf85833e8027cc990fb79fc862f001c
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/.yardopts
CHANGED
data/Gemfile
ADDED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,25 +1,31 @@
|
|
1
1
|
# drain
|
2
2
|
|
3
3
|
* [Homepage](https://github.com/DamienRobert/drain#readme)
|
4
|
-
* [Gems]("https://rubygems.org/gems/drain)
|
5
4
|
* [Issues](https://github.com/DamienRobert/drain/issues)
|
6
|
-
* [Documentation](http://rubydoc.info/gems/drain
|
5
|
+
* [Documentation](http://rubydoc.info/gems/drain)
|
7
6
|
* [Email](mailto:Damien.Olivier.Robert+gems at gmail.com)
|
8
7
|
|
8
|
+
[![Gem Version](https://img.shields.io/gem/v/drain.svg)](https://rubygems.org/gems/drain)
|
9
|
+
[![Build Status](https://travis-ci.org/DamienRobert/drain.svg?branch=master)](https://travis-ci.org/DamienRobert/drain)
|
10
|
+
|
9
11
|
## Description
|
10
12
|
|
11
13
|
Drain is a small set of libraries that I use in my other gems.
|
12
14
|
The Api is far from stable yet, so use at your own risk!
|
13
15
|
|
16
|
+
## Warning
|
17
|
+
|
18
|
+
For now the API is experimental and some parts are not ready to use!
|
19
|
+
|
14
20
|
## Install
|
15
21
|
|
16
22
|
$ gem install drain
|
17
23
|
|
18
24
|
## Copyright
|
19
25
|
|
20
|
-
Copyright
|
26
|
+
Copyright © 2015–2017 Damien Robert
|
21
27
|
|
22
|
-
MIT License. See
|
28
|
+
MIT License. See [LICENSE.txt](./LICENSE.txt) for details.
|
23
29
|
|
24
30
|
Some of the code is inspired by other project, in general I give proper
|
25
|
-
|
31
|
+
acknowledgement in the corresponding file.
|
data/Rakefile
CHANGED
@@ -1,20 +1,16 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
1
|
require 'rake'
|
5
2
|
|
6
3
|
begin
|
7
|
-
gem 'rubygems-tasks', '~> 0.2'
|
8
4
|
require 'rubygems/tasks'
|
9
|
-
|
10
|
-
|
5
|
+
Gem::Tasks.new(sign: {checksum: true, pgp: true},
|
6
|
+
scm: {status: true}) do |tasks|
|
7
|
+
tasks.console.command = 'pry'
|
8
|
+
end
|
11
9
|
rescue LoadError => e
|
12
10
|
warn e.message
|
13
|
-
warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
|
14
11
|
end
|
15
12
|
|
16
13
|
require 'rake/testtask'
|
17
|
-
|
18
14
|
Rake::TestTask.new do |test|
|
19
15
|
test.libs << 'test'
|
20
16
|
test.pattern = 'test/**/test_*.rb'
|
@@ -22,13 +18,12 @@ Rake::TestTask.new do |test|
|
|
22
18
|
end
|
23
19
|
|
24
20
|
begin
|
25
|
-
gem 'yard', '~> 0.8'
|
26
21
|
require 'yard'
|
27
|
-
|
28
|
-
YARD::Rake::YardocTask.new
|
22
|
+
YARD::Rake::YardocTask.new
|
29
23
|
rescue LoadError => e
|
30
24
|
task :yard do
|
31
|
-
|
25
|
+
warn e.message
|
32
26
|
end
|
33
27
|
end
|
34
28
|
task :doc => :yard
|
29
|
+
|
data/drain.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'yaml'
|
4
2
|
|
5
3
|
Gem::Specification.new do |gem|
|
@@ -10,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
10
8
|
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
9
|
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
10
|
|
13
|
-
require '
|
14
|
-
|
11
|
+
require 'dr/version'
|
12
|
+
DR::VERSION
|
15
13
|
end
|
16
14
|
|
17
15
|
gem.summary = gemspec['summary']
|
@@ -24,6 +22,16 @@ Gem::Specification.new do |gem|
|
|
24
22
|
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
25
23
|
|
26
24
|
gem.files = `git ls-files`.split($/)
|
25
|
+
|
26
|
+
`git submodule --quiet foreach --recursive pwd`.split($/).each do |submodule|
|
27
|
+
submodule.sub!("#{Dir.pwd}/",'')
|
28
|
+
|
29
|
+
Dir.chdir(submodule) do
|
30
|
+
`git ls-files`.split($/).map do |subpath|
|
31
|
+
gem.files << File.join(submodule,subpath)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
27
35
|
gem.files = glob[gemspec['files']] if gemspec['files']
|
28
36
|
|
29
37
|
gem.executables = gemspec.fetch('executables') do
|
@@ -38,7 +46,7 @@ Gem::Specification.new do |gem|
|
|
38
46
|
%w[ext lib].select { |dir| File.directory?(dir) }
|
39
47
|
})
|
40
48
|
|
41
|
-
gem.requirements = gemspec['requirements']
|
49
|
+
gem.requirements = Array(gemspec['requirements'])
|
42
50
|
gem.required_ruby_version = gemspec['required_ruby_version']
|
43
51
|
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
44
52
|
gem.post_install_message = gemspec['post_install_message']
|
@@ -56,4 +64,6 @@ Gem::Specification.new do |gem|
|
|
56
64
|
gem.add_development_dependency(name,split[versions])
|
57
65
|
end
|
58
66
|
end
|
67
|
+
|
68
|
+
gem.metadata['yard.run']='yri'
|
59
69
|
end
|
data/gemspec.yml
CHANGED
@@ -8,6 +8,7 @@ email: Damien.Olivier.Robert+gems@gmail.com
|
|
8
8
|
homepage: https://github.com/DamienRobert/drain#readme
|
9
9
|
|
10
10
|
development_dependencies:
|
11
|
-
minitest: ~> 5.0
|
12
|
-
|
13
|
-
|
11
|
+
minitest: "~> 5.0"
|
12
|
+
rake: "~> 10"
|
13
|
+
rubygems-tasks: "~> 0.2"
|
14
|
+
yard: "~> 0.8"
|
data/lib/dr.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'dr/version'
|
data/lib/{drain → dr}/base.rb
RENAMED
File without changes
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DR
|
2
|
+
module Converter
|
3
|
+
extend self
|
4
|
+
#convert an obj to hash, using 'methods' for the methods attributes
|
5
|
+
def to_hash(obj=nil, methods:[], recursive: false, check: false, compact: false)
|
6
|
+
return {} if obj.nil?
|
7
|
+
obj||=self
|
8
|
+
stack=[*obj]
|
9
|
+
processed=[]
|
10
|
+
klass=stack.first.class
|
11
|
+
h={}
|
12
|
+
while !stack.empty?
|
13
|
+
obj=stack.shift
|
14
|
+
next if processed.include?(obj)
|
15
|
+
processed << obj
|
16
|
+
attributes={}
|
17
|
+
methods.each do |m|
|
18
|
+
next if check and !obj.respond_to? m
|
19
|
+
v=obj.public_send(m)
|
20
|
+
attributes[m]=v
|
21
|
+
if recursive
|
22
|
+
vals=v.kind_of?(Enumerable) ? v.to_a.flatten : [v]
|
23
|
+
vals.select! {|v| v.kind_of?(klass)}
|
24
|
+
stack.concat(vals)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
attributes=attributes.values.first if compact and attributes.keys.length == 1
|
28
|
+
h[obj]=attributes
|
29
|
+
end
|
30
|
+
h
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
File without changes
|
@@ -0,0 +1,284 @@
|
|
1
|
+
module DR
|
2
|
+
class Eruby
|
3
|
+
module BindingHelper
|
4
|
+
extend self
|
5
|
+
#complement TOPLEVEL_BINDING
|
6
|
+
def empty_binding
|
7
|
+
#wraps into anonymous module so that 'def foo' do not pollute namespace
|
8
|
+
Module.new do
|
9
|
+
#regenerate a new binding
|
10
|
+
return binding
|
11
|
+
end
|
12
|
+
end
|
13
|
+
#empty binding (at first) that stays the same and can be shared
|
14
|
+
EMPTY_BINDING = empty_binding
|
15
|
+
BLANK_OBJECT=Object.new
|
16
|
+
|
17
|
+
# add variables values to a binding; variables is a Hash
|
18
|
+
def add_variables(variables, _binding=empty_binding)
|
19
|
+
eval variables.collect{|k,v| "#{k} = variables[#{k.inspect}]; "}.join, _binding
|
20
|
+
_binding
|
21
|
+
end
|
22
|
+
|
23
|
+
#From Tilt/template.rb
|
24
|
+
#return a string extracting local_keys from a hash named _context
|
25
|
+
def local_extraction(local_keys, context_name: '_context')
|
26
|
+
local_keys.map do |k|
|
27
|
+
if k.to_s =~ /\A[a-z_][a-zA-Z_0-9]*\z/
|
28
|
+
"#{k} = #{context_name}[#{k.inspect}]"
|
29
|
+
else
|
30
|
+
raise "invalid locals key: #{k.inspect} (keys must be variable names)"
|
31
|
+
end
|
32
|
+
end.join("\n")+"\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
module EngineHelper
|
38
|
+
### Stolen from erubis
|
39
|
+
## eval(@src) with binding object
|
40
|
+
def result(_binding_or_hash=BindingHelper.empty_binding)
|
41
|
+
_arg = _binding_or_hash
|
42
|
+
if _arg.is_a?(Hash)
|
43
|
+
_b=BindingHelper.add_variables(_arg, BindingHelper.empty_binding)
|
44
|
+
elsif _arg.is_a?(Binding)
|
45
|
+
_b = _arg
|
46
|
+
elsif _arg.nil?
|
47
|
+
_b = binding
|
48
|
+
else
|
49
|
+
raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.")
|
50
|
+
end
|
51
|
+
return eval(@src, _b, (@filename || '(eruby'))
|
52
|
+
#erb.rb:
|
53
|
+
# if @safe_level
|
54
|
+
# proc {
|
55
|
+
# $SAFE = @safe_level
|
56
|
+
# eval(@src, b, (@filename || '(erb)'), @lineno)
|
57
|
+
# }.call
|
58
|
+
end
|
59
|
+
|
60
|
+
#Note that when the result is not used afterwards via "instance_eval"
|
61
|
+
#then the Klass of binding is important when src has 'def foo...'
|
62
|
+
#If set, locals should be an array of variable names
|
63
|
+
def compile(wrap: :proc, bind: BindingHelper.empty_binding, locals: nil, pre: nil, post: nil, context_name: '_context')
|
64
|
+
src=@src
|
65
|
+
src=BindingHelper.local_extraction(locals, context_name: context_name)+src if locals
|
66
|
+
src=pre+"\n"+src if pre
|
67
|
+
src<< post+"\n" if post
|
68
|
+
to_eval=case wrap
|
69
|
+
when :eval; @src
|
70
|
+
when :lambda; "lambda { |#{context_name}| #{src} }"
|
71
|
+
when :proc; "Proc.new { |#{context_name}| #{src} }"
|
72
|
+
when :module; "Module.new { |#{context_name}| #{src} }"
|
73
|
+
when :unbound
|
74
|
+
#wrapping in a method allows us to pass a block to a code
|
75
|
+
#calling yield
|
76
|
+
require 'dr/ruby_ext/meta_ext'
|
77
|
+
return Meta.get_unbound_evalmethod('eruby', src, args: context_name)
|
78
|
+
when :unbound_instance
|
79
|
+
#here we wrap in a method that the calls instance_eval
|
80
|
+
require 'dr/ruby_ext/meta_ext'
|
81
|
+
return Meta.get_unbound_evalmethod('eruby', <<-RUBY, args: context_name)
|
82
|
+
self.instance_eval do
|
83
|
+
#{src}
|
84
|
+
end
|
85
|
+
RUBY
|
86
|
+
when :string
|
87
|
+
src.to_s
|
88
|
+
else
|
89
|
+
warn "wrap meth #{warn} not understood, defaulting to String"
|
90
|
+
src
|
91
|
+
end
|
92
|
+
return eval(to_eval, bind, "(wrap #{@filename})")
|
93
|
+
end
|
94
|
+
|
95
|
+
## by default invoke context.instance_eval(@src)
|
96
|
+
def evaluate(_context=Context.new, compile: {}, **opts, &b)
|
97
|
+
#I prefer to pass context as a keyword, but we allow to pass it as
|
98
|
+
#an argument to respect erubis's api
|
99
|
+
_context=opts[:context] if opts.key?(:context)
|
100
|
+
_context = Context.new(_context) if _context.is_a?(Hash)
|
101
|
+
vars=opts[:vars]
|
102
|
+
compile[:locals]||=vars.keys if vars
|
103
|
+
#to pass a block we need to wrap in a method
|
104
|
+
compile[:wrap]||=:unbound_instance if b
|
105
|
+
_proc=compile(**compile)
|
106
|
+
Eruby.evaluate(_proc, context: _context, **opts, &b)
|
107
|
+
end
|
108
|
+
|
109
|
+
## if object is an Class or Module then define instance method to it,
|
110
|
+
## else define singleton method to it.
|
111
|
+
def def_method(object, method_name, filename=nil)
|
112
|
+
m = object.is_a?(Module) ? :module_eval : :instance_eval
|
113
|
+
object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(eruby)')
|
114
|
+
#erb.rb: src = self.src.sub(/^(?!#|$)/) {"def #{methodname}\n"} << "\nend\n" #This pattern insert the 'def' after lines with leading comments
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Template
|
119
|
+
include EngineHelper
|
120
|
+
|
121
|
+
def initialize(src, filename: nil)
|
122
|
+
if src.respond_to?(:read)
|
123
|
+
filename=src unless filename
|
124
|
+
src=src.read
|
125
|
+
end
|
126
|
+
@filename=filename || self.class.inspect
|
127
|
+
@src=src
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
module ClassHelpers
|
133
|
+
def process_eruby(eruby_src, **opts, &b)
|
134
|
+
src=Eruby::Engine.new(eruby_src).src
|
135
|
+
process_ruby(src, **opts, &b)
|
136
|
+
end
|
137
|
+
|
138
|
+
def process_ruby(src, src_info: nil, **opts, &b)
|
139
|
+
Template.new(src, filename: src_info).evaluate(**opts, &b)
|
140
|
+
end
|
141
|
+
|
142
|
+
def evaluate(_proc, context: Context.new, vars: nil, &b)
|
143
|
+
#we can only pass the block b when we get an UnboundMethod
|
144
|
+
if _proc.is_a?(UnboundMethod)
|
145
|
+
vars={} if _proc.arity > 0 and vars.nil?
|
146
|
+
if !vars.nil?
|
147
|
+
_proc.bind(context).call(vars,&b)
|
148
|
+
else
|
149
|
+
_proc.bind(context).call(&b)
|
150
|
+
end
|
151
|
+
elsif _proc.is_a?(String)
|
152
|
+
#in this case we cannot pass vars
|
153
|
+
warn "Cannot pass variables when _proc is a String" unless vars.nil?
|
154
|
+
context.instance_eval(_proc)
|
155
|
+
else
|
156
|
+
if context.nil?
|
157
|
+
if !vars.nil?
|
158
|
+
_proc.to_proc.call(vars,&b)
|
159
|
+
else
|
160
|
+
_proc.to_proc(&b)
|
161
|
+
end
|
162
|
+
else
|
163
|
+
warn "Cannot pass block in context.instance_eval" unless b.nil?
|
164
|
+
if !vars.nil?
|
165
|
+
context.instance_exec(vars,&_proc)
|
166
|
+
else
|
167
|
+
context.instance_eval(&_proc)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def include(template, **opts)
|
174
|
+
file=File.expand_path(template)
|
175
|
+
Dir.chdir(File.dirname(file)) do |cwd|
|
176
|
+
erb = Engine.new(File.read(file))
|
177
|
+
#if context is not empty, then we probably want to evaluate
|
178
|
+
if opts[:evaluate] or opts[:context]
|
179
|
+
r=erb.evaluate(opts[:context])
|
180
|
+
else
|
181
|
+
bind=opts[:bind]||binding
|
182
|
+
r=erb.result(bind)
|
183
|
+
end
|
184
|
+
#if using erubis, it is better to invoke the template in <%= =%> than
|
185
|
+
#to use chomp=true
|
186
|
+
r=r.chomp if opts[:chomp]
|
187
|
+
return r
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
extend ClassHelpers
|
193
|
+
|
194
|
+
begin
|
195
|
+
require 'erubi'
|
196
|
+
Engine=::Erubi::Engine
|
197
|
+
rescue LoadError
|
198
|
+
require 'erubis'
|
199
|
+
Engine=::Erubis::Eruby
|
200
|
+
rescue LoadError
|
201
|
+
require 'erb'
|
202
|
+
Engine=::ERB
|
203
|
+
end
|
204
|
+
#prepend so that we have the same implementation
|
205
|
+
Engine.__send__(:prepend, EngineHelper)
|
206
|
+
|
207
|
+
## Copy/Pasted from erubis context.rb
|
208
|
+
## # context object for Engine#evaluate
|
209
|
+
##
|
210
|
+
## ex.
|
211
|
+
## template = <<'END'
|
212
|
+
## Hello <%= @user %>!
|
213
|
+
## <% for item in @list %>
|
214
|
+
## - <%= item %>
|
215
|
+
## <% end %>
|
216
|
+
## END
|
217
|
+
##
|
218
|
+
## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c'])
|
219
|
+
## # or
|
220
|
+
## # context = Erubis::Context.new
|
221
|
+
## # context[:user] = 'World'
|
222
|
+
## # context[:list] = ['a', 'b', 'c']
|
223
|
+
##
|
224
|
+
## eruby = Erubis::Eruby.new(template)
|
225
|
+
## print eruby.evaluate(context)
|
226
|
+
##
|
227
|
+
class Context
|
228
|
+
include Enumerable
|
229
|
+
|
230
|
+
def initialize(hash=nil)
|
231
|
+
hash.each do |name, value|
|
232
|
+
self[name] = value
|
233
|
+
end if hash
|
234
|
+
end
|
235
|
+
|
236
|
+
def [](key)
|
237
|
+
return instance_variable_get("@#{key}")
|
238
|
+
end
|
239
|
+
|
240
|
+
def []=(key, value)
|
241
|
+
return instance_variable_set("@#{key}", value)
|
242
|
+
end
|
243
|
+
|
244
|
+
def keys
|
245
|
+
return instance_variables.collect { |name| name[1..-1] }
|
246
|
+
end
|
247
|
+
|
248
|
+
def each
|
249
|
+
instance_variables.each do |name|
|
250
|
+
key = name[1..-1]
|
251
|
+
value = instance_variable_get(name)
|
252
|
+
yield(key, value)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# Was to_hash, but changed to 'to_h' in commit 25d0e1e4b1a4ada40fd64945eb79823ea074d030
|
257
|
+
# Indeed otherwise passing it to 'evaluate' it get interpreted as the options rather than as a context
|
258
|
+
# cf https://bugs.ruby-lang.org/issues/12884
|
259
|
+
# corrected in ruby 2.4.1?
|
260
|
+
def to_h
|
261
|
+
hash = {}
|
262
|
+
self.keys.each { |key| hash[key] = self[key] }
|
263
|
+
return hash
|
264
|
+
end
|
265
|
+
|
266
|
+
def update(context_or_hash)
|
267
|
+
arg = context_or_hash
|
268
|
+
if arg.is_a?(Hash)
|
269
|
+
arg.each do |key, val|
|
270
|
+
self[key] = val
|
271
|
+
end
|
272
|
+
else
|
273
|
+
arg.instance_variables.each do |varname|
|
274
|
+
key = varname[1..-1]
|
275
|
+
val = arg.instance_variable_get(varname)
|
276
|
+
self[key] = val
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|