class Device
@@all = Array.new
attr_reader :mac, :name
# need this funny bit to alias class methods
class << self
alias_method :old_new, :new
end
# if the device is already listed in all_devices, return the
# existing object instead of creating a new one
def self.new *args, &b
@@all.each do |device|
return device if args.first == device.mac
end
this = self.old_new *args, &b
@@all << this
this
end
def initialize mac, name
@mac = mac
@name = name
@sent = {}
end
def sent? file
@sent[file]
end
def send! file, timeout=8
result = `ussp-push --timeo #{timeout} #{@mac}@ #{file} #{file.name}`
@sent[file] = ($?.to_i == 0 && result.scan(/Connection established/))
end
def self.find_new
device_objects = Array.new
devices_string = `hcitool scan --flush`
available_devices = devices_string.scan(/[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]\t[^\n]*/i)
available_devices.each do |detected_device|
mac_addr = detected_device.scan(/[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]/i).first
dev_name = detected_device.scan(/\t[^\n]*/i).first.gsub(/\t/,'')
new_device = Device.new mac_addr, dev_name
device_objects << new_device
end
device_objects
end
end
Refactorings
No refactoring yet !
Pavel Gorbokon
April 6, 2010, April 06, 2010 20:39, permalink
Instead of aliasing new you can just call super
class Device
@@devices = {}
def self.new mac, *args
@@devices[mac] ||= super
end
MAC_PATTERN = /(?:[0-9a-f]{2}\:){5}[0-9a-f]{2}/
NAME_PATTERN = /[^\n]*/
DEVICE_SCAN_REGEXP = /(#{MAC_PATTERN})\t(#{NAME_PATTERN})/
def self.find_new
devices = `hcitool scan --flush`
devices.scan(DEVICE_SCAN_REGEXP).map do |(mac, name)|
Device.new mac, name
end
end
attr_reader :mac, :name
def initialize mac, name
@mac, @name = mac, name
@sent = {}
end
def sent? file
@sent[file]
end
def send! file, timeout=8
result = `ussp-push --timeo #{timeout} #{@mac}@ #{file} #{file.name}`
@sent[file] = ($?.to_i == 0 && result.scan(/Connection established/))
end
end
I've put together a quick ruby bluetooth class. All it does at the moment is search for devices and send files to any selected device (which is all I need). It uses system commands, which isn't ideal, but I can't really see a better way. The main bits which need refactoring are the bits where I mess about with the new method... not sure what can be done here, and the find_new class method, which scans for devices and returns an array of Device objects (I'm terrible with regular expressions).