fathom 0.3.7 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +7 -5
- data/.document +2 -2
- data/Gemfile +9 -10
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +29 -90
- data/Rakefile +34 -32
- data/VERSION +1 -1
- data/fathom.gemspec +105 -0
- data/features/fathom.feature +26 -0
- data/features/step_definitions/fathom_steps.rb +23 -0
- data/features/support/env.rb +13 -0
- data/lib/ext/array.rb +6 -2
- data/lib/ext/string.rb +86 -7
- data/lib/fathom.rb +51 -88
- data/lib/fathom/behaviors/attribute_system.rb +91 -0
- data/lib/fathom/behaviors/context_behavior.rb +28 -0
- data/lib/fathom/behaviors/plugins.rb +16 -0
- data/lib/fathom/contexts/network_population.rb +47 -0
- data/lib/fathom/contexts/network_traversal.rb +4 -0
- data/lib/fathom/data/adjacency_matrix.rb +27 -0
- data/lib/fathom/data/definition.rb +22 -0
- data/lib/fathom/data/edge.rb +58 -0
- data/lib/fathom/data/network.rb +35 -0
- data/lib/fathom/data/outcome.rb +30 -0
- data/lib/fathom/data/property.rb +31 -0
- data/lib/fathom/data/variable.rb +59 -0
- data/lib/fathom/roles/general_graph_tools.rb +87 -0
- data/lib/fathom/roles/network_builder.rb +61 -0
- data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
- data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
- data/spec/fathom/behaviors/plugins_spec.rb +80 -0
- data/spec/fathom/contexts/network_population_spec.rb +55 -0
- data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
- data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
- data/spec/fathom/data/definition_spec.rb +19 -0
- data/spec/fathom/data/edge_spec.rb +77 -0
- data/spec/fathom/data/network_spec.rb +72 -0
- data/spec/fathom/data/outcome_spec.rb +17 -0
- data/spec/fathom/data/property_spec.rb +17 -0
- data/spec/fathom/data/variable_spec.rb +101 -0
- data/spec/fathom/ext/array_spec.rb +17 -0
- data/spec/fathom/ext/string_spec.rb +90 -0
- data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
- data/spec/fathom/roles/network_builder_spec.rb +90 -0
- data/spec/fathom_spec.rb +28 -49
- data/spec/spec_helper.rb +7 -11
- data/spec/support/context_behavior.rb +14 -0
- data/spec/support/custom_matchers.rb +12 -0
- data/spec/support/files.rb +8 -0
- data/spec/support/network.yml +42 -0
- metadata +133 -174
- data/.bundle/config +0 -2
- data/.gitignore +0 -6
- data/Gemfile.lock +0 -42
- data/TODO.md +0 -127
- data/autotest/discover.rb +0 -1
- data/lib/ext/faster_csv.rb +0 -1
- data/lib/ext/open_struct.rb +0 -17
- data/lib/fathom/agent.rb +0 -48
- data/lib/fathom/agent/agent_cluster.rb +0 -23
- data/lib/fathom/agent/properties.rb +0 -48
- data/lib/fathom/archive/causal_graph.rb +0 -12
- data/lib/fathom/archive/concept.rb +0 -83
- data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
- data/lib/fathom/archive/inverter.rb +0 -20
- data/lib/fathom/archive/n2.rb +0 -198
- data/lib/fathom/archive/n3.rb +0 -119
- data/lib/fathom/archive/node.rb +0 -97
- data/lib/fathom/archive/noodle.rb +0 -136
- data/lib/fathom/archive/scratch.rb +0 -45
- data/lib/fathom/distributions.rb +0 -8
- data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
- data/lib/fathom/distributions/discrete_uniform.rb +0 -25
- data/lib/fathom/distributions/gaussian.rb +0 -46
- data/lib/fathom/distributions/uniform.rb +0 -35
- data/lib/fathom/import.rb +0 -85
- data/lib/fathom/import/csv_import.rb +0 -59
- data/lib/fathom/import/import_node.rb +0 -17
- data/lib/fathom/import/yaml_import.rb +0 -74
- data/lib/fathom/knowledge_base.rb +0 -46
- data/lib/fathom/knowledge_base/search.rb +0 -19
- data/lib/fathom/monte_carlo_set.rb +0 -152
- data/lib/fathom/node.rb +0 -139
- data/lib/fathom/node/belief_node.rb +0 -121
- data/lib/fathom/node/cpm_node.rb +0 -100
- data/lib/fathom/node/data_collection.rb +0 -97
- data/lib/fathom/node/data_node.rb +0 -22
- data/lib/fathom/node/decision.rb +0 -11
- data/lib/fathom/node/discrete_node.rb +0 -41
- data/lib/fathom/node/fact.rb +0 -24
- data/lib/fathom/node/mc_node.rb +0 -70
- data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
- data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
- data/lib/fathom/node/plausible_range.rb +0 -98
- data/lib/fathom/simulation.rb +0 -59
- data/lib/fathom/simulation/tick_methods.rb +0 -25
- data/lib/fathom/simulation/tick_simulation.rb +0 -12
- data/lib/fathom/value_description.rb +0 -79
- data/lib/options_hash.rb +0 -186
- data/spec/ext/array_spec.rb +0 -10
- data/spec/ext/faster_csv_spec.rb +0 -10
- data/spec/ext/open_struct_spec.rb +0 -20
- data/spec/ext/string_spec.rb +0 -7
- data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
- data/spec/fathom/agent_spec.rb +0 -51
- data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
- data/spec/fathom/distributions/gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/uniform_spec.rb +0 -0
- data/spec/fathom/import/csv_import_spec.rb +0 -52
- data/spec/fathom/import/import_node_spec.rb +0 -10
- data/spec/fathom/import/yaml_import_spec.rb +0 -73
- data/spec/fathom/import_spec.rb +0 -36
- data/spec/fathom/knowledge_base_spec.rb +0 -20
- data/spec/fathom/monte_carlo_set_spec.rb +0 -149
- data/spec/fathom/node/belief_node_spec.rb +0 -180
- data/spec/fathom/node/cpm_node_spec.rb +0 -144
- data/spec/fathom/node/data_collection_spec.rb +0 -26
- data/spec/fathom/node/data_node_spec.rb +0 -102
- data/spec/fathom/node/decision_spec.rb +0 -15
- data/spec/fathom/node/discrete_node_spec.rb +0 -56
- data/spec/fathom/node/fact_spec.rb +0 -33
- data/spec/fathom/node/mc_node_spec.rb +0 -66
- data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
- data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
- data/spec/fathom/node/plausible_range_spec.rb +0 -151
- data/spec/fathom/node_spec.rb +0 -172
- data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
- data/spec/fathom/simulation_spec.rb +0 -24
- data/spec/fathom/value_description_spec.rb +0 -70
- data/spec/support/demo.yml +0 -17
- data/spec/support/demo_agent.rb +0 -8
- data/spec/support/dummy_numeric_node.rb +0 -8
- data/spec/support/fact.yml +0 -11
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
begin
|
3
|
+
Bundler.setup(:default, :development)
|
4
|
+
rescue Bundler::BundlerError => e
|
5
|
+
$stderr.puts e.message
|
6
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
exit e.status_code
|
8
|
+
end
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
11
|
+
require 'fathom'
|
12
|
+
|
13
|
+
require 'rspec/expectations'
|
data/lib/ext/array.rb
CHANGED
data/lib/ext/string.rb
CHANGED
@@ -1,8 +1,39 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Inflector
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
5
|
+
if first_letter_in_uppercase
|
6
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
7
|
+
else
|
8
|
+
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def underscore(camel_cased_word)
|
13
|
+
word = camel_cased_word.to_s.dup
|
14
|
+
word.gsub!(/::/, '/')
|
15
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
16
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
17
|
+
word.tr!("-", "_")
|
18
|
+
word.downcase!
|
19
|
+
word
|
20
|
+
end
|
21
|
+
|
22
|
+
def dasherize(underscored_word)
|
23
|
+
underscored_word.gsub(/_/, '-')
|
24
|
+
end
|
25
|
+
|
26
|
+
def demodulize(class_name_in_module)
|
27
|
+
class_name_in_module.to_s.gsub(/^.*::/, '')
|
28
|
+
end
|
29
|
+
|
30
|
+
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
|
31
|
+
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
|
32
|
+
end
|
33
|
+
|
3
34
|
if Module.method(:const_get).arity == 1
|
4
|
-
def constantize
|
5
|
-
names =
|
35
|
+
def constantize(camel_cased_word)
|
36
|
+
names = camel_cased_word.split('::')
|
6
37
|
names.shift if names.empty? || names.first.empty?
|
7
38
|
|
8
39
|
constant = Object
|
@@ -12,8 +43,8 @@ class String
|
|
12
43
|
constant
|
13
44
|
end
|
14
45
|
else
|
15
|
-
def constantize #:nodoc:
|
16
|
-
names =
|
46
|
+
def constantize(camel_cased_word) #:nodoc:
|
47
|
+
names = camel_cased_word.split('::')
|
17
48
|
names.shift if names.empty? || names.first.empty?
|
18
49
|
|
19
50
|
constant = Object
|
@@ -23,5 +54,53 @@ class String
|
|
23
54
|
constant
|
24
55
|
end
|
25
56
|
end
|
57
|
+
|
58
|
+
def ordinalize(number)
|
59
|
+
if (11..13).include?(number.to_i % 100)
|
60
|
+
"#{number}th"
|
61
|
+
else
|
62
|
+
case number.to_i % 10
|
63
|
+
when 1; "#{number}st"
|
64
|
+
when 2; "#{number}nd"
|
65
|
+
when 3; "#{number}rd"
|
66
|
+
else "#{number}th"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class String
|
73
|
+
def constantize
|
74
|
+
Inflector.constantize(self)
|
75
|
+
end
|
76
|
+
|
77
|
+
def camelize(first_letter_in_uppercase = true)
|
78
|
+
Inflector.camelize(self, first_letter_in_uppercase)
|
79
|
+
end
|
80
|
+
|
81
|
+
def underscore
|
82
|
+
Inflector.underscore(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
def dasherize
|
86
|
+
Inflector.dasherize(self)
|
87
|
+
end
|
88
|
+
|
89
|
+
def demodulize
|
90
|
+
Inflector.demodulize(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
94
|
+
Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
95
|
+
end
|
96
|
+
|
97
|
+
def ordinalize
|
98
|
+
Inflector.ordinalize(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
def wrap(col=80)
|
102
|
+
# http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
|
103
|
+
gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/, "\\1\\3\n")
|
104
|
+
end
|
26
105
|
|
27
|
-
end
|
106
|
+
end
|
data/lib/fathom.rb
CHANGED
@@ -1,103 +1,66 @@
|
|
1
1
|
# ================
|
2
2
|
# = Dependencies =
|
3
3
|
# ================
|
4
|
+
Dir.glob("#{File.dirname(__FILE__)}/ext/*.rb").each { |file| require file}
|
4
5
|
|
5
|
-
|
6
|
-
$:.unshift(File.dirname(__FILE__))
|
7
|
-
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'fathom')))
|
8
|
-
|
9
|
-
require 'rubygems'
|
10
|
-
|
11
|
-
require "gsl"
|
12
|
-
require 'options_hash'
|
13
|
-
|
14
|
-
require 'ext/open_struct'
|
15
|
-
require 'ext/array'
|
16
|
-
require 'ext/string'
|
6
|
+
require 'uuid'
|
17
7
|
|
18
8
|
module Fathom
|
19
|
-
lib = File.expand_path(File.dirname(__FILE__))
|
20
|
-
$LOAD_PATH.unshift(lib)
|
21
9
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# autoload :DataNode, "node/data_node"
|
28
|
-
# autoload :DiscreteNode, "node/discrete_node"
|
29
|
-
# autoload :MCNode, "node/mc_node"
|
30
|
-
# autoload :PlausibleRange, "node/plausible_range"
|
31
|
-
# autoload :Fact, "node/fact"
|
32
|
-
# autoload :Decision, "node/decision"
|
33
|
-
# autoload :CPMNode, 'node/cpm_node'
|
34
|
-
#
|
35
|
-
# autoload :ValueDescription, "value_description"
|
36
|
-
# autoload :MonteCarloSet, "monte_carlo_set"
|
37
|
-
# autoload :KnowledgeBase, "knowledge_base"
|
38
|
-
#
|
39
|
-
# autoload :Import, "import"
|
40
|
-
# autoload :ImportNode, "import/import_node"
|
41
|
-
# autoload :YAMLImport, 'import/yaml_import'
|
42
|
-
# autoload :CSVImport, 'import/csv_import'
|
43
|
-
# # autoload :RDFImport, 'import/rdf_import'
|
44
|
-
# # autoload :SQLiteImport, 'import/sqlite_import'
|
45
|
-
#
|
46
|
-
# autoload :Simulation, 'simulation'
|
47
|
-
# autoload :TickMethods, 'simulation/tick_methods'
|
48
|
-
# autoload :TickSimulation, 'simulation/tick_simulation'
|
49
|
-
#
|
50
|
-
# autoload :Agent, 'agent'
|
51
|
-
# autoload :Properties, 'agent/properties'
|
52
|
-
# autoload :AgentCluster, 'agent/agent_cluster'
|
53
|
-
#
|
54
|
-
# autoload :EnforcedName, 'node/node_extensions/enforced_name'
|
55
|
-
# autoload :NumericMethods, 'node/node_extensions/numeric_methods'
|
56
|
-
|
57
|
-
require 'distributions'
|
58
|
-
module Distributions
|
59
|
-
autoload :Gaussian, 'distributions/gaussian'
|
60
|
-
autoload :Uniform, 'distributions/uniform'
|
61
|
-
autoload :DiscreteGaussian, 'distributions/discrete_gaussian'
|
62
|
-
autoload :DiscreteUniform, 'distributions/discrete_uniform'
|
10
|
+
class Config
|
11
|
+
attr_writer :storage
|
12
|
+
def storage
|
13
|
+
@storage ||= Hash
|
14
|
+
end
|
63
15
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
16
|
+
|
17
|
+
# =================
|
18
|
+
# = Configuration =
|
19
|
+
# =================
|
20
|
+
class << self
|
21
|
+
# A reset-able configuration that provides access to other services (pod storage, say)
|
22
|
+
def config
|
23
|
+
@config ||= Config.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# The reset on the configuration
|
27
|
+
def reset_config!
|
28
|
+
@config = Config.new
|
29
|
+
end
|
67
30
|
end
|
68
|
-
|
31
|
+
|
69
32
|
end
|
70
33
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Fathom.autoload :Node, "node"
|
75
|
-
Fathom.autoload :BeliefNode, "node/belief_node"
|
76
|
-
Fathom.autoload :DataCollection, "node/data_collection"
|
77
|
-
Fathom.autoload :DataNode, "node/data_node"
|
78
|
-
Fathom.autoload :DiscreteNode, "node/discrete_node"
|
79
|
-
Fathom.autoload :MCNode, "node/mc_node"
|
80
|
-
Fathom.autoload :PlausibleRange, "node/plausible_range"
|
81
|
-
Fathom.autoload :Fact, "node/fact"
|
82
|
-
Fathom.autoload :Decision, "node/decision"
|
83
|
-
Fathom.autoload :CPMNode, 'node/cpm_node'
|
84
|
-
|
85
|
-
Fathom.autoload :ValueDescription, "value_description"
|
86
|
-
Fathom.autoload :MonteCarloSet, "monte_carlo_set"
|
87
|
-
Fathom.autoload :KnowledgeBase, "knowledge_base"
|
34
|
+
def path(path)
|
35
|
+
File.expand_path("../fathom/#{path}", __FILE__)
|
36
|
+
end
|
88
37
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
Fathom.autoload :
|
38
|
+
# =============
|
39
|
+
# = Behaviors =
|
40
|
+
# =============
|
41
|
+
Fathom.autoload :AttributeSystem, path('behaviors/attribute_system')
|
42
|
+
Fathom.autoload :ContextBehavior, path('behaviors/context_behavior')
|
43
|
+
Fathom.autoload :Plugins, path('behaviors/plugins')
|
93
44
|
|
94
|
-
|
95
|
-
|
96
|
-
|
45
|
+
# ===============
|
46
|
+
# = Data Models =
|
47
|
+
# ===============
|
48
|
+
Fathom.autoload :AdjacencyMatrix, path('data/adjacency_matrix')
|
49
|
+
Fathom.autoload :Definition, path('data/definition')
|
50
|
+
Fathom.autoload :Edge, path('data/edge')
|
51
|
+
Fathom.autoload :Network, path('data/network')
|
52
|
+
Fathom.autoload :Outcome, path('data/outcome')
|
53
|
+
Fathom.autoload :Property, path('data/property')
|
54
|
+
Fathom.autoload :Variable, path('data/variable')
|
97
55
|
|
98
|
-
|
99
|
-
|
100
|
-
|
56
|
+
# ============
|
57
|
+
# = Contexts =
|
58
|
+
# ============
|
59
|
+
Fathom.autoload :NetworkPopulation, path('contexts/network_population')
|
60
|
+
Fathom.autoload :NetworkTraversal, path('contexts/network_traversal')
|
101
61
|
|
102
|
-
|
103
|
-
|
62
|
+
# =========
|
63
|
+
# = Roles =
|
64
|
+
# =========
|
65
|
+
Fathom.autoload :NetworkBuilder, path('roles/network_builder')
|
66
|
+
Fathom.autoload :GeneralGraphTools, path('roles/general_graph_tools')
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Fathom
|
2
|
+
|
3
|
+
# This is a simple way to use thin Ruby classes to only store data values for attributes.
|
4
|
+
# In this way, we can have data models that can have various roles injected into them at
|
5
|
+
# runtime and perform fairly well. We can also have other kinds of data models mixed into
|
6
|
+
# Fathom, such as an ActiveRecord or DataMapper model, and we can just ignore this system
|
7
|
+
# altogether.
|
8
|
+
#
|
9
|
+
# It is important that it is easy to set an attributes_proxy. Other Fathom gems
|
10
|
+
# (say fm-redis, if I were to write that gem) could override the AttributeSystem default
|
11
|
+
# attributes to store data in a Redis data store directly. This is what the set_attributes_proxy
|
12
|
+
# is designed to do here.
|
13
|
+
#
|
14
|
+
# Example Usage:
|
15
|
+
# require 'memcache'
|
16
|
+
# CACHE = MemCache.new 'localhost:11211', :namespace => 'my_project'
|
17
|
+
# CACHE[1] = {:name => 'special'}
|
18
|
+
#
|
19
|
+
# class MyClass
|
20
|
+
# extend Fathom::Plugins
|
21
|
+
# plugin Fathom::AttributeSystem
|
22
|
+
#
|
23
|
+
# attribute :name
|
24
|
+
# attribute :value, 1
|
25
|
+
#
|
26
|
+
# def initialize(attrs={})
|
27
|
+
# @attributes = attrs
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# obj = MyClass.new(CACHE[1])
|
32
|
+
# obj.name # => special
|
33
|
+
# obj.value # => 1
|
34
|
+
module AttributeSystem
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
|
38
|
+
# Define an attribute, or property of this class.
|
39
|
+
# Useful for very thin, generic Ruby classes for Data models.
|
40
|
+
def attribute(getter_name, default=nil)
|
41
|
+
|
42
|
+
# Define a getter on the object
|
43
|
+
define_method(getter_name) do
|
44
|
+
|
45
|
+
target = send(self.class.attributes_proxy)
|
46
|
+
|
47
|
+
return target[getter_name] unless target.respond_to?(:has_key?)
|
48
|
+
|
49
|
+
if target.has_key?(getter_name)
|
50
|
+
target[getter_name]
|
51
|
+
else
|
52
|
+
self.class.attribute_defaults[getter_name]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Define a setter on the object
|
57
|
+
define_method("#{getter_name}=") do |value|
|
58
|
+
send(self.class.attributes_proxy)[getter_name] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
# Define a default on the object
|
62
|
+
attribute_defaults[getter_name] = default
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
# Defines where the attributes are stored for the target class.
|
67
|
+
def set_attributes_proxy(value)
|
68
|
+
@attributes_proxy = value
|
69
|
+
end
|
70
|
+
|
71
|
+
def attributes_proxy
|
72
|
+
@attributes_proxy ||= :attributes
|
73
|
+
end
|
74
|
+
|
75
|
+
def attribute_defaults
|
76
|
+
@attribute_defaults ||= {}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module InstanceMethods
|
81
|
+
|
82
|
+
# Defines an attributes getter and defaults it to a Hash.
|
83
|
+
def attributes
|
84
|
+
@attributes ||= {}
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end # AttributeSystem
|
90
|
+
|
91
|
+
end # Fathom
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fathom
|
2
|
+
module ContextBehavior
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
def default_class(value=nil)
|
7
|
+
@default_class = value if value
|
8
|
+
@default_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def new(*attrs, &block)
|
12
|
+
target = attrs.shift
|
13
|
+
target ||= default_class.new if default_class
|
14
|
+
raise ArgumentError, "You must provide a target object to build this context." unless target
|
15
|
+
obj = super(*attrs, &block)
|
16
|
+
obj.send(:instance_variable_set, :@object, target)
|
17
|
+
obj
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module InstanceMethods
|
22
|
+
attr_reader :object
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.configure(base)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Fathom
|
2
|
+
module Plugins
|
3
|
+
def plugins
|
4
|
+
@plugins ||= []
|
5
|
+
end
|
6
|
+
|
7
|
+
def plugin(mod)
|
8
|
+
include mod unless mod.const_defined?(:InstanceMethods)
|
9
|
+
extend mod::ClassMethods if mod.const_defined?(:ClassMethods)
|
10
|
+
include mod::InstanceMethods if mod.const_defined?(:InstanceMethods)
|
11
|
+
mod.configure(self) if mod.respond_to?(:configure)
|
12
|
+
plugins << mod
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fathom
|
2
|
+
class NetworkPopulation
|
3
|
+
# ============
|
4
|
+
# = Behavior =
|
5
|
+
# ============
|
6
|
+
extend Plugins
|
7
|
+
plugin ContextBehavior
|
8
|
+
default_class Network
|
9
|
+
|
10
|
+
# Uses YAML to populate a network.
|
11
|
+
# Expects a format in the YAML that mirrors the data models we are using.
|
12
|
+
#
|
13
|
+
# Dependencies:
|
14
|
+
# * yaml (standard library)
|
15
|
+
# * open-uri (standard library)
|
16
|
+
#
|
17
|
+
# Roles: NetworkBuilder
|
18
|
+
#
|
19
|
+
# Usage:
|
20
|
+
# @context = NetworkPopulation.new(some_network)
|
21
|
+
# @context.import_records_from_yaml(:filename => 'some_network.yml')
|
22
|
+
def import_records_from_yaml(opts={})
|
23
|
+
require 'yaml'
|
24
|
+
require 'open-uri'
|
25
|
+
object.extend NetworkBuilder
|
26
|
+
hash = extract_data_hash_from_parameters(opts)
|
27
|
+
object.from_hash(hash)
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# Contract: return a hash, the best one you can find, or an empty one.
|
33
|
+
def extract_data_hash_from_parameters(opts)
|
34
|
+
if opts[:filename]
|
35
|
+
data_from_yaml_file(opts[:filename])
|
36
|
+
else
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Contract: return a hash or raise an error
|
42
|
+
def data_from_yaml_file(filename)
|
43
|
+
YAML.load_file(filename)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|