artoo 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +14 -25
- data/Gemfile.lock +9 -10
- data/README.md +7 -2
- data/artoo.gemspec +8 -0
- data/examples/ardrone.rb +2 -2
- data/examples/ardrone_nav.rb +3 -3
- data/examples/ardrone_nav_video_wii.rb +3 -3
- data/examples/ardrone_nav_wiiclassic.rb +2 -2
- data/examples/ardrone_wiiclassic.rb +57 -16
- data/examples/christmas_roomba.rb +18 -0
- data/examples/sphero_wiichuck.rb +28 -0
- data/examples/wiichuck.rb +12 -0
- data/lib/artoo/adaptors/adaptor.rb +7 -0
- data/lib/artoo/adaptors/roomba.rb +43 -0
- data/lib/artoo/basic.rb +79 -0
- data/lib/artoo/drivers/motor.rb +58 -0
- data/lib/artoo/drivers/roomba.rb +155 -0
- data/lib/artoo/drivers/servo.rb +49 -0
- data/lib/artoo/drivers/wiichuck.rb +86 -7
- data/lib/artoo/drivers/wiiclassic.rb +80 -76
- data/lib/artoo/events.rb +34 -0
- data/lib/artoo/robot.rb +25 -134
- data/lib/artoo/version.rb +1 -1
- data/test/drivers/motor_test.rb +40 -0
- data/test/drivers/servo_test.rb +45 -0
- data/test/drivers/wiiclassic_test.rb +6 -1
- metadata +120 -16
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ed97e1d66baccca21165b0960b2ed18212b2a1d4
|
4
|
+
data.tar.gz: 77e070f5faa53a75532d5c73f87c2016d9e0f23a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6566a8f925b396b38e0641e64548f42787d0611852733077697efad840b972281cc0ac8d218801476593a590c52287802a6bdd8bb25758c19430eaa4c20c4e67
|
7
|
+
data.tar.gz: 4107fcfa598cc71a9d3a5e11f26b1885336e0b5c64ae264fc13150162db6fe4055d54db3984007c46886a3c74306c92fc3dadb66392d1b41b820888b34662af0
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -3,29 +3,18 @@ source "http://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in artoo.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
gem '
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem 'multi_json'
|
6
|
+
# these are for specific hardware, they have to be here for tests
|
7
|
+
gem 'hybridgroup-firmata'
|
8
|
+
gem 'hybridgroup-sphero'
|
9
|
+
gem 'hybridgroup-argus'
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
gem 'sass'
|
23
|
-
gem 'coffee-script'
|
24
|
-
gem 'sprockets'
|
25
|
-
gem 'compass'
|
26
|
-
gem 'bootstrap-sass'
|
27
|
-
gem 'guard'
|
28
|
-
gem 'guard-livereload'
|
29
|
-
gem 'guard-sprockets'
|
30
|
-
gem 'guard-compass'
|
31
|
-
end
|
11
|
+
# For the front end web application
|
12
|
+
gem 'sass'
|
13
|
+
gem 'coffee-script'
|
14
|
+
gem 'sprockets'
|
15
|
+
gem 'compass'
|
16
|
+
gem 'bootstrap-sass'
|
17
|
+
gem 'guard'
|
18
|
+
gem 'guard-livereload'
|
19
|
+
gem 'guard-sprockets'
|
20
|
+
gem 'guard-compass'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
artoo (0.
|
4
|
+
artoo (0.2.0)
|
5
|
+
active_support (~> 3.0)
|
6
|
+
celluloid-io (~> 0.12)
|
7
|
+
multi_json (~> 1.6)
|
8
|
+
rake (~> 10.0)
|
9
|
+
reel (~> 0.3)
|
5
10
|
|
6
11
|
GEM
|
7
12
|
remote: http://rubygems.org/
|
@@ -69,12 +74,11 @@ GEM
|
|
69
74
|
lumberjack (1.0.2)
|
70
75
|
metaclass (0.0.1)
|
71
76
|
method_source (0.8.1)
|
72
|
-
minitest (4.
|
77
|
+
minitest (4.6.2)
|
73
78
|
mocha (0.13.2)
|
74
79
|
metaclass (~> 0.0.1)
|
75
80
|
multi_json (1.6.1)
|
76
81
|
nio4r (0.4.3)
|
77
|
-
nio4r (0.4.3-java)
|
78
82
|
pry (0.9.12)
|
79
83
|
coderay (~> 1.0.5)
|
80
84
|
method_source (~> 0.8)
|
@@ -112,10 +116,8 @@ PLATFORMS
|
|
112
116
|
ruby
|
113
117
|
|
114
118
|
DEPENDENCIES
|
115
|
-
active_support
|
116
119
|
artoo!
|
117
120
|
bootstrap-sass
|
118
|
-
celluloid-io
|
119
121
|
coffee-script
|
120
122
|
compass
|
121
123
|
guard
|
@@ -125,10 +127,7 @@ DEPENDENCIES
|
|
125
127
|
hybridgroup-argus
|
126
128
|
hybridgroup-firmata
|
127
129
|
hybridgroup-sphero
|
128
|
-
minitest
|
129
|
-
mocha
|
130
|
-
multi_json
|
131
|
-
rake
|
132
|
-
reel
|
130
|
+
minitest (~> 4.6)
|
131
|
+
mocha (~> 0.13)
|
133
132
|
sass
|
134
133
|
sprockets
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Artoo is a micro-framework for robotics using Ruby.
|
|
6
6
|
|
7
7
|
Artoo provides a simple, yet powerful domain-specific language (DSL) for robotics and physical computing.
|
8
8
|
|
9
|
-
[](https://codeclimate.com/github/hybridgroup/artoo)
|
9
|
+
[](https://codeclimate.com/github/hybridgroup/artoo) [](https://travis-ci.org/hybridgroup/artoo)
|
10
10
|
|
11
11
|
## Examples:
|
12
12
|
|
@@ -71,9 +71,14 @@ SPHEROS.each {|p|
|
|
71
71
|
SpheroRobot.work!(robots)
|
72
72
|
```
|
73
73
|
|
74
|
+
Ruby versions supported: Ruby 2.0, 1.9.3, JRuby 1.7.2, and Rubinius 2.0
|
75
|
+
|
76
|
+
|
74
77
|
Artoo is conceptualy influenced by Sinatra (https://github.com/sinatra/sinatra) as well as borrowing some code from it.
|
75
78
|
|
76
|
-
Artoo provides a robust actor-based messaging architecture, that can support fully multi-threaded operation and high-concurrency, as long as it is supported by the Ruby version in which it is executing.
|
79
|
+
Artoo provides a robust actor-based messaging architecture, that can support fully multi-threaded operation and high-concurrency, as long as it is supported by the Ruby version in which it is executing. This means you will need to use JRuby or Rubinius for maximum concurrency.
|
80
|
+
|
81
|
+
To a large extent, this is due to being built on top of Celluloid (https://github.com/celluloid/celluloid), Celluloid::IO (https://github.com/celluloid/celluloid-io), and Reel (https://github.com/celluloid/reel).
|
77
82
|
|
78
83
|
## API:
|
79
84
|
|
data/artoo.gemspec
CHANGED
@@ -18,4 +18,12 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'celluloid-io', '~> 0.12'
|
23
|
+
s.add_runtime_dependency 'reel', '~> 0.3'
|
24
|
+
s.add_runtime_dependency 'multi_json', '~> 1.6'
|
25
|
+
s.add_runtime_dependency 'active_support', '~> 3.0'
|
26
|
+
s.add_runtime_dependency 'rake', '~> 10.0'
|
27
|
+
s.add_development_dependency 'minitest', '~> 4.6'
|
28
|
+
s.add_development_dependency 'mocha', '~> 0.13'
|
21
29
|
end
|
data/examples/ardrone.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
5
|
|
6
6
|
work do
|
@@ -9,4 +9,4 @@ work do
|
|
9
9
|
|
10
10
|
after(25.seconds) { drone.hover.land }
|
11
11
|
after(30.seconds) { drone.stop }
|
12
|
-
end
|
12
|
+
end
|
data/examples/ardrone_nav.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
5
|
|
6
|
-
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
|
7
7
|
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
8
|
|
9
9
|
work do
|
@@ -19,4 +19,4 @@ def nav_update(*data)
|
|
19
19
|
data[1].drone_state.each do |name, val|
|
20
20
|
p "#{name}: #{val}"
|
21
21
|
end
|
22
|
-
end
|
22
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
5
|
|
6
|
-
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
|
7
7
|
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
8
|
|
9
|
-
connection :videodrone, :adaptor => :ardrone_video, :port => '192.168.1.
|
9
|
+
connection :videodrone, :adaptor => :ardrone_video, :port => '192.168.1.1:5555'
|
10
10
|
device :video, :driver => :ardrone_video, :connection => :videodrone
|
11
11
|
|
12
12
|
connection :arduino, :adaptor => :firmata, :port => "8023"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'artoo'
|
2
2
|
|
3
|
-
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.
|
3
|
+
connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
|
4
4
|
device :drone, :driver => :ardrone, :connection => :ardrone
|
5
5
|
|
6
|
-
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.
|
6
|
+
connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
|
7
7
|
device :nav, :driver => :ardrone_navigation, :connection => :navigation
|
8
8
|
|
9
9
|
connection :arduino, :adaptor => :firmata, :port => "8023"
|
@@ -24,25 +24,66 @@ work do
|
|
24
24
|
on classic, :home_button => proc { drone.emergency }
|
25
25
|
on classic, :start_button => proc { drone.start }
|
26
26
|
on classic, :select_button => proc { drone.stop }
|
27
|
-
|
28
|
-
on classic, :
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
|
28
|
+
on classic, :left_joystick => proc { |*value|
|
29
|
+
pair = value[1]
|
30
|
+
if pair[:y] > 0
|
31
|
+
drone.forward(validate_pitch(pair[:y], @offsets[:ly]))
|
32
|
+
elsif pair[:y] < 0
|
33
|
+
drone.backward(validate_pitch(pair[:y], @offsets[:ly]))
|
34
|
+
else
|
35
|
+
drone.forward(0.0)
|
36
|
+
end
|
37
|
+
|
38
|
+
if pair[:x] > 0
|
39
|
+
drone.right(validate_pitch(pair[:x], @offsets[:lx]))
|
40
|
+
elsif pair[:x] < 0
|
41
|
+
drone.left(validate_pitch(pair[:x], @offsets[:lx]))
|
42
|
+
else
|
43
|
+
drone.right(0.0)
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
on classic, :right_joystick => proc { |*value|
|
48
|
+
pair = value[1]
|
49
|
+
if pair[:y] > 0
|
50
|
+
drone.up(validate_pitch(pair[:y], @offsets[:ry]))
|
51
|
+
elsif pair[:y] < 0
|
52
|
+
drone.down(validate_pitch(pair[:y], @offsets[:ry]))
|
53
|
+
else
|
54
|
+
drone.up(0.0)
|
55
|
+
end
|
56
|
+
}
|
57
|
+
|
58
|
+
on classic, :right_trigger => proc { |*value|
|
59
|
+
if value[1] > 0
|
60
|
+
drone.turn_right(validate_pitch(value[1], @offsets[:rt]))
|
61
|
+
else
|
62
|
+
drone.turn_right(0.0)
|
63
|
+
end
|
64
|
+
}
|
65
|
+
|
66
|
+
on classic, :left_trigger => proc { |*value|
|
67
|
+
if value[1] > 0
|
68
|
+
drone.turn_left(validate_pitch(value[1], @offsets[:lt]))
|
69
|
+
else
|
70
|
+
drone.turn_left(0.0)
|
71
|
+
end
|
36
72
|
}
|
37
|
-
on classic, :rotate_left => proc { drone.turn_left(@rotate_pitch) }
|
38
|
-
on classic, :rotate_right => proc { drone.turn_right(@rotate_pitch) }
|
39
|
-
on classic, :reset_rotate => proc { drone.turn_left(0.0) }
|
40
|
-
on classic, :reset_altitude => proc { drone.up(0.0) }
|
41
73
|
end
|
42
74
|
|
43
75
|
def init_settings
|
44
|
-
@rotate_pitch = 0.5
|
45
|
-
@fly_pitch = 0.7
|
46
|
-
@altitude_pitch = 1
|
47
76
|
@toggle_camera = 0
|
77
|
+
@offsets = {
|
78
|
+
:ry => 12.0,
|
79
|
+
:ly => 27.0,
|
80
|
+
:lx => 27.0,
|
81
|
+
:rt => 27.0,
|
82
|
+
:lt => 12.0
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def validate_pitch(data, offset)
|
87
|
+
value = data.abs / offset
|
88
|
+
value >= 0.1 ? (value <= 1.0 ? value.round(2) : 1.0) : 0.0
|
48
89
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
begin
|
2
|
+
require 'artoo'
|
3
|
+
rescue LoadError
|
4
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__),'..', 'lib')))
|
5
|
+
require "artoo"
|
6
|
+
end
|
7
|
+
|
8
|
+
connection :roomba, :adaptor => :roomba, :port => '/dev/tty.usbserial-A2001yzl'
|
9
|
+
device :roomba, :driver => :roomba, :connection => :roomba
|
10
|
+
|
11
|
+
work do
|
12
|
+
roomba.safe_mode
|
13
|
+
roomba.nudge_left
|
14
|
+
roomba.nudge_right
|
15
|
+
roomba.nudge_right
|
16
|
+
roomba.nudge_left
|
17
|
+
roomba.sing_jingle_bells
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :sphero, :adaptor => :sphero, :port => '127.0.0.1:4560'
|
4
|
+
device :sphero, :driver => :sphero
|
5
|
+
|
6
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
7
|
+
device :wiichuck, :driver => :wiichuck, :connection => :arduino, :interval => 0.1
|
8
|
+
|
9
|
+
work do
|
10
|
+
init_settings
|
11
|
+
on wiichuck, :c_button => proc {}
|
12
|
+
on wiichuck, :z_button => proc {}
|
13
|
+
on wiichuck, :joystick => proc { |*value|
|
14
|
+
@heading = heading(value[1])
|
15
|
+
}
|
16
|
+
every(1.seconds) do
|
17
|
+
puts "Rolling..."
|
18
|
+
sphero.roll 20, @heading
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def init_settings
|
23
|
+
@heading = 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def heading(value)
|
27
|
+
(180.0 - (Math.atan2(value[:y],value[:x]) * (180.0 / Math::PI))).round
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'artoo'
|
2
|
+
|
3
|
+
connection :arduino, :adaptor => :firmata, :port => "8023"
|
4
|
+
device :wiichuck, :driver => :wiichuck, :connection => :arduino, :interval => 0.1
|
5
|
+
|
6
|
+
work do
|
7
|
+
on wiichuck, :c_button => proc { puts "c button pressed!" }
|
8
|
+
on wiichuck, :z_button => proc { puts "z button pressed!" }
|
9
|
+
on wiichuck, :joystick => proc { |*value|
|
10
|
+
puts "joystick x: #{value[1][:x]}, y: #{value[1][:y]}"
|
11
|
+
}
|
12
|
+
end
|
@@ -49,6 +49,13 @@ module Artoo
|
|
49
49
|
def connect_to_udp
|
50
50
|
@udp_socket ||= UDPSocket.new
|
51
51
|
end
|
52
|
+
|
53
|
+
def connect_to_serial(speed=57600, data_bits=8, stop_bits=1, parity=SerialPort::NONE)
|
54
|
+
require 'serialport'
|
55
|
+
@sp = SerialPort.new(port.port, speed, data_bits, stop_bits, parity)
|
56
|
+
rescue LoadError
|
57
|
+
Logger.error "Please 'gem install hybridgroup-serialport' for serial port support."
|
58
|
+
end
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'artoo/adaptors/adaptor'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Adaptors
|
5
|
+
# Connect to a Roomba (http://www.irobot.com/en/us/robots/Educators/Create.aspx)
|
6
|
+
class Roomba < Adaptor
|
7
|
+
|
8
|
+
attr_reader :sp
|
9
|
+
|
10
|
+
def finalize
|
11
|
+
if connected?
|
12
|
+
@sp.close
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect
|
17
|
+
if port.is_serial?
|
18
|
+
@sp = connect_to_serial
|
19
|
+
@sp.dtr = 0
|
20
|
+
@sp.rts = 0
|
21
|
+
else
|
22
|
+
@sp = connect_to_tcp
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def send_bytes(bytes)
|
28
|
+
bytes = [bytes] unless bytes.respond_to?(:map)
|
29
|
+
bytes.map!(&:chr)
|
30
|
+
Logger.debug "sending: #{bytes.inspect}"
|
31
|
+
res = []
|
32
|
+
bytes.each{|b| res << @sp.write(b) }
|
33
|
+
Logger.debug "returned: #{res.inspect}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def disconnect
|
37
|
+
@sp.close
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/artoo/basic.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
module Artoo
|
3
|
+
module Basic
|
4
|
+
# Taken from Sinatra codebase
|
5
|
+
# Sets an option to the given value. If the value is a proc,
|
6
|
+
# the proc will be called every time the option is accessed.
|
7
|
+
def set(option, value = (not_set = true), ignore_setter = false, &block)
|
8
|
+
raise ArgumentError if block and !not_set
|
9
|
+
value, not_set = block, false if block
|
10
|
+
|
11
|
+
if not_set
|
12
|
+
raise ArgumentError unless option.respond_to?(:each)
|
13
|
+
option.each { |k,v| set(k, v) }
|
14
|
+
return self
|
15
|
+
end
|
16
|
+
|
17
|
+
if respond_to?("#{option}=") and not ignore_setter
|
18
|
+
return __send__("#{option}=", value)
|
19
|
+
end
|
20
|
+
|
21
|
+
setter = proc { |val| set option, val, true }
|
22
|
+
getter = proc { value }
|
23
|
+
|
24
|
+
case value
|
25
|
+
when Proc
|
26
|
+
getter = value
|
27
|
+
when Symbol, Fixnum, FalseClass, TrueClass, NilClass
|
28
|
+
getter = value.inspect
|
29
|
+
when Hash
|
30
|
+
setter = proc do |val|
|
31
|
+
val = value.merge val if Hash === val
|
32
|
+
set option, val, true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
define_singleton_method("#{option}=", setter) if setter
|
37
|
+
define_singleton_method(option, getter) if getter
|
38
|
+
define_singleton_method("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# Taken from Sinatra codebase
|
43
|
+
CALLERS_TO_IGNORE = [ # :nodoc:
|
44
|
+
/lib\/artoo.*\.rb$/, # artoo code
|
45
|
+
/^\(.*\)$/, # generated code
|
46
|
+
/rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks
|
47
|
+
/active_support/, # active_support require hacks
|
48
|
+
/bundler(\/runtime)?\.rb/, # bundler require hacks
|
49
|
+
/<internal:/, # internal in ruby >= 1.9.2
|
50
|
+
/src\/kernel\/bootstrap\/[A-Z]/ # maglev kernel files
|
51
|
+
]
|
52
|
+
|
53
|
+
# Taken from Sinatra codebase
|
54
|
+
# Like Kernel#caller but excluding certain magic entries and without
|
55
|
+
# line / method information; the resulting array contains filenames only.
|
56
|
+
def caller_files
|
57
|
+
cleaned_caller(1).flatten
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Taken from Sinatra codebase
|
63
|
+
def define_singleton_method(name, content = Proc.new)
|
64
|
+
# replace with call to singleton_class once we're 1.9 only
|
65
|
+
(class << self; self; end).class_eval do
|
66
|
+
undef_method(name) if method_defined? name
|
67
|
+
String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Taken from Sinatra codebase
|
72
|
+
# Like Kernel#caller but excluding certain magic entries
|
73
|
+
def cleaned_caller(keep = 3)
|
74
|
+
caller(1).
|
75
|
+
map { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
|
76
|
+
reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|