Class: Beholder

Inherits:
Object
  • Object
show all
Defined in:
lib/beholder.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBeholder

Returns a new instance of Beholder.



13
14
15
16
17
18
19
20
21
# File 'lib/beholder.rb', line 13

def initialize
  @paths_to_watch = []
  @sent_an_int = false
  @mappings = {}
  @working_directory = Dir.pwd
  @be_verbose = ARGV.include?("-v") || ARGV.include?("--verbose")
  @treasure_maps = {}
  @corpses = ["#{@working_directory}/.treasure_map.rb", "#{@working_directory}/treasure_map.rb", "#{@working_directory}/config/treasure_map.rb"]
end

Instance Attribute Details

#be_verboseObject (readonly)

Returns the value of attribute be_verbose.



11
12
13
# File 'lib/beholder.rb', line 11

def be_verbose
  @be_verbose
end

#corpsesObject (readonly)

Returns the value of attribute corpses.



11
12
13
# File 'lib/beholder.rb', line 11

def corpses
  @corpses
end

#mappingsObject (readonly)

Returns the value of attribute mappings.



11
12
13
# File 'lib/beholder.rb', line 11

def mappings
  @mappings
end

#paths_to_watchObject (readonly)

Returns the value of attribute paths_to_watch.



11
12
13
# File 'lib/beholder.rb', line 11

def paths_to_watch
  @paths_to_watch
end

#sent_an_intObject (readonly)

Returns the value of attribute sent_an_int.



11
12
13
# File 'lib/beholder.rb', line 11

def sent_an_int
  @sent_an_int
end

#the_eyeObject (readonly)

Returns the value of attribute the_eye.



11
12
13
# File 'lib/beholder.rb', line 11

def the_eye
  @the_eye
end

#treasure_mapsObject (readonly)

Returns the value of attribute treasure_maps.



11
12
13
# File 'lib/beholder.rb', line 11

def treasure_maps
  @treasure_maps
end

#working_directoryObject (readonly)

Returns the value of attribute working_directory.



11
12
13
# File 'lib/beholder.rb', line 11

def working_directory
  @working_directory
end

Class Method Details

.cast_thy_gazeObject



23
24
25
26
27
28
# File 'lib/beholder.rb', line 23

def self.cast_thy_gaze
  beholder = new
  beholder.read_all_the_maps
  beholder.prepare_for_interlopers    
  beholder.open_your_eye
end

Instance Method Details



100
101
102
# File 'lib/beholder.rb', line 100

def blink
  @sent_an_int = false
end

#cast_feeble_mindObject



52
53
54
# File 'lib/beholder.rb', line 52

def cast_feeble_mind
  @treasure_maps = {}
end

#close_your_eyeObject



104
105
106
107
# File 'lib/beholder.rb', line 104

def close_your_eye
  the_eye.shutdown
  exit
end

#identify_stolen_treasure(treasure) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/beholder.rb', line 109

def identify_stolen_treasure(treasure)
  treasure_maps.each do |name, treasure_locations|
    
    treasure_locations.each do |stolen_by_enemy, spell| 
    
      if spell_components = treasure.match(stolen_by_enemy)
        say "Found the stolen treasure using the #{name} map "
        return spell.cast!(spell_components)
      end
    
    end
  
  end
  
  puts "Unknown file: #{treasure}"
  return []
end

#keep_a_watchful_eye_for(*paths) ⇒ Object



56
57
58
# File 'lib/beholder.rb', line 56

def keep_a_watchful_eye_for(*paths)
  @paths_to_watch.concat(paths)
end

#loot_corpsesObject



90
91
92
93
94
95
96
97
98
# File 'lib/beholder.rb', line 90

def loot_corpses
  corpses.each do |corpse|
    if File.exist?(corpse)
      say "Found a treasure map on #{corpse}"
      instance_eval(File.readlines(corpse).join("\n"))
      return
    end
  end    
end

#map_for(map_name) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:

  • _self (Beholder)

    the object that the method was called on



40
41
42
43
44
45
# File 'lib/beholder.rb', line 40

def map_for(map_name)
  @treasure_maps[map_name] ||= []
  @current_map = @treasure_maps[map_name]
  yield self if block_given?
  @current_map = nil
end

#notice_thief_taking(treasure) ⇒ Object



142
143
144
145
146
# File 'lib/beholder.rb', line 142

def notice_thief_taking(treasure)
  say "#{treasure} changed"
  coordinates = treasure.map { |t| identify_stolen_treasure(t) }.uniq.compact
  reclaim_stolen_treasure_at coordinates
end

#open_your_eyeObject



30
31
32
33
34
35
36
37
38
# File 'lib/beholder.rb', line 30

def open_your_eye
  say("Watching the following locations:\n  #{paths_to_watch.join(", ")}")
  @the_eye = FSEvents::Stream.watch(paths_to_watch) do |treasure_chest|
    notice_thief_taking(treasure_chest.modified_files)
    blink
    puts "\n\nWaiting to hear from the disk since #{Time.now}"
  end
  @the_eye.run
end

#prepare_for_interlopersObject



148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/beholder.rb', line 148

def prepare_for_interlopers
  trap 'INT' do
    if @sent_an_int then      
      puts "   A second INT?  Ok, I get the message.  Shutting down now."
      close_your_eye
    else
      puts "   Did you just send me an INT? Ugh.  I'll quit for real if you do it again."
      @sent_an_int = true
      Kernel.sleep 1.5
    end
  end
end

#prepare_spell_for(arcane_enemy, &spell) ⇒ Object Also known as: add_mapping



47
48
49
# File 'lib/beholder.rb', line 47

def prepare_spell_for(arcane_enemy, &spell)
  @current_map << [arcane_enemy, spell]
end

#read_all_the_mapsObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/beholder.rb', line 60

def read_all_the_maps
  map_for(:default_dungeon) do |wizard|
    
    wizard.keep_a_watchful_eye_for 'app', 'config', 'lib', 'examples'
   
    wizard.prepare_spell_for /\/app\/(.*)\.rb/ do |spell_component|
      ["examples/#{spell_component[1]}.rb"]
    end
    
    wizard.prepare_spell_for /\/lib\/(.*)\.rb/ do |spell_component|
      ["examples/lib/#{spell_component[1]}_example.rb"]
    end
    
    wizard.prepare_spell_for /\/examples\/(.*)_example\.rb/ do |spell_component|
      ["examples/#{spell_component[1]}_example.rb"]
    end
    
    wizard.prepare_spell_for /\/examples\/example_helper\.rb/ do |spell_component|
      Dir["examples/**/*_example.rb"]
    end
  
    wizard.prepare_spell_for /\/config/ do
      Dir["examples/**/*_example.rb"]
    end

  end
  
  loot_corpses
end

#reclaim_stolen_treasure_at(coordinates) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/beholder.rb', line 127

def reclaim_stolen_treasure_at(coordinates)
  coordinates.flatten!

  coordinates.reject! do |coordinate|
    not_there = !File.exist?(coordinate)
    puts "Example #{coordinate} does not actually exist." if not_there
    not_there
  end
  
  return if coordinates.empty?
  
  puts "\nRunning #{coordinates.join(', ').inspect}" 
  system "ruby #{coordinates.join(' ')}"
end