sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 9dd4f50b9f62ab5642241359bf6f7c291ccfa738
parent 5debe177ddf8c0e4268f0e6b36f1eedc4b9cfd49
Author: William Morgan <wmorgan-sup@masanjin.net>
Date:   Wed, 12 Aug 2009 13:14:34 -0400

rewrite Singleton to not require i_am_the_instance

The flip side is that you have to use .init instead of .new.

Diffstat:
M bin/sup | 4 ++--
M bin/sup-add | 2 +-
M bin/sup-config | 2 +-
M bin/sup-dump | 4 ++--
M bin/sup-recover-sources | 2 +-
M bin/sup-sync | 2 +-
M bin/sup-sync-back | 2 +-
M bin/sup-tweak-labels | 2 +-
M lib/sup.rb | 24 ++++++++++++------------
M lib/sup/account.rb | 2 --
M lib/sup/buffer.rb | 2 --
M lib/sup/contact.rb | 2 --
M lib/sup/crypto.rb | 2 --
M lib/sup/draft.rb | 1 -
M lib/sup/hook.rb | 2 --
M lib/sup/index.rb | 1 -
M lib/sup/label.rb | 2 --
M lib/sup/poll.rb | 2 --
M lib/sup/sent.rb | 1 -
M lib/sup/source.rb | 1 -
M lib/sup/suicide.rb | 1 -
M lib/sup/undo.rb | 1 -
M lib/sup/update.rb | 1 -
M lib/sup/util.rb | 18 ++++++++++--------
24 files changed, 32 insertions(+), 51 deletions(-)
diff --git a/bin/sup b/bin/sup
@@ -129,7 +129,7 @@ def stop_cursing
 end
 module_function :start_cursing, :stop_cursing
 
-Index.new
+Index.init
 begin
   Index.lock
 rescue Index::LockError => e
@@ -178,7 +178,7 @@ begin
   log "starting curses"
   start_cursing
 
-  bm = BufferManager.new
+  bm = BufferManager.init
   Colormap.new.populate_colormap
 
   log "initializing mail index buffer"
diff --git a/bin/sup-add b/bin/sup-add
@@ -77,7 +77,7 @@ end
 
 $terminal.wrap_at = :auto
 Redwood::start
-index = Redwood::Index.new
+index = Redwood::Index.init
 
 index.lock_or_die
 
diff --git a/bin/sup-config b/bin/sup-config
@@ -151,7 +151,7 @@ end
 
 $terminal.wrap_at = :auto
 Redwood::start
-index = Redwood::Index.new
+index = Redwood::Index.init
 Redwood::SourceManager.load_sources
 
 say <<EOS
diff --git a/bin/sup-dump b/bin/sup-dump
@@ -21,8 +21,8 @@ No options.
 EOS
 end
 
-index = Redwood::Index.new
-Redwood::SourceManager.new
+index = Redwood::Index.init
+Redwood::SourceManager.init
 index.load
 
 index.each_message :load_spam => true, :load_deleted => true, :load_killed => true do |m|
diff --git a/bin/sup-recover-sources b/bin/sup-recover-sources
@@ -50,7 +50,7 @@ end.parse(ARGV)
 require "sup"
 Redwood::start
 puts "loading index..."
-index = Redwood::Index.new
+index = Redwood::Index.init
 index.load
 puts "loaded index of #{index.size} messages"
 
diff --git a/bin/sup-sync b/bin/sup-sync
@@ -95,7 +95,7 @@ target = [:new, :changed, :all, :restored].find { |x| opts[x] } || :new
 op = [:asis, :restore, :discard].find { |x| opts[x] } || :asis
 
 Redwood::start
-index = Redwood::Index.new
+index = Redwood::Index.init
 
 restored_state = if opts[:restore]
   dump = {}
diff --git a/bin/sup-sync-back b/bin/sup-sync-back
@@ -65,7 +65,7 @@ EOS
 end
 
 Redwood::start
-index = Redwood::Index.new
+index = Redwood::Index.init
 index.lock_or_die
 
 deleted_fp, spam_fp = nil
diff --git a/bin/sup-tweak-labels b/bin/sup-tweak-labels
@@ -61,7 +61,7 @@ Trollop::die "nothing to do: no labels to add or remove" if add_labels.empty? &&
 
 Redwood::start
 begin
-  index = Redwood::Index.new
+  index = Redwood::Index.init
   index.load
 
   source_ids = if opts[:all_sources]
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -107,17 +107,17 @@ module Redwood
   end
 
   def start
-    Redwood::SentManager.new $config[:sent_source] || 'sup://sent'
-    Redwood::ContactManager.new Redwood::CONTACT_FN
-    Redwood::LabelManager.new Redwood::LABEL_FN
-    Redwood::AccountManager.new $config[:accounts]
-    Redwood::DraftManager.new Redwood::DRAFT_DIR
-    Redwood::UpdateManager.new
-    Redwood::PollManager.new
-    Redwood::SuicideManager.new Redwood::SUICIDE_FN
-    Redwood::CryptoManager.new
-    Redwood::UndoManager.new
-    Redwood::SourceManager.new
+    Redwood::SentManager.init $config[:sent_source] || 'sup://sent'
+    Redwood::ContactManager.init Redwood::CONTACT_FN
+    Redwood::LabelManager.init Redwood::LABEL_FN
+    Redwood::AccountManager.init $config[:accounts]
+    Redwood::DraftManager.init Redwood::DRAFT_DIR
+    Redwood::UpdateManager.init
+    Redwood::PollManager.init
+    Redwood::SuicideManager.init Redwood::SUICIDE_FN
+    Redwood::CryptoManager.init
+    Redwood::UndoManager.init
+    Redwood::SourceManager.init
   end
 
   def finish
@@ -230,7 +230,7 @@ require "sup/hook"
 ## we have to initialize this guy first, because other classes must
 ## reference it in order to register hooks, and they do that at parse
 ## time.
-Redwood::HookManager.new Redwood::HOOK_DIR
+Redwood::HookManager.init Redwood::HOOK_DIR
 
 ## everything we need to get logging working
 require "sup/buffer"
diff --git a/lib/sup/account.rb b/lib/sup/account.rb
@@ -25,8 +25,6 @@ class AccountManager
 
     add_account accounts[:default], true
     accounts.each { |k, v| add_account v, false unless k == :default }
-
-    self.class.i_am_the_instance self
   end
 
   def user_accounts; @accounts.keys; end
diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
@@ -196,8 +196,6 @@ EOS
     @flash = nil
     @shelled = @asking = false
     @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
-
-    self.class.i_am_the_instance self
   end
 
   def buffers; @name_map.to_a; end
diff --git a/lib/sup/contact.rb b/lib/sup/contact.rb
@@ -22,8 +22,6 @@ class ContactManager
         @a2p[aalias] = p unless aalias.nil? || aalias.empty?
       end
     end
-
-    self.class.i_am_the_instance self
   end
 
   def contacts; @p2a.keys end
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -13,10 +13,8 @@ class CryptoManager
 
   def initialize
     @mutex = Mutex.new
-    self.class.i_am_the_instance self
 
     bin = `which gpg`.chomp
-
     @cmd =
       case bin
       when /\S/
diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
@@ -7,7 +7,6 @@ class DraftManager
   def initialize dir
     @dir = dir
     @source = nil
-    self.class.i_am_the_instance self
   end
 
   def self.source_name; "sup://drafts"; end
diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb
@@ -79,8 +79,6 @@ class HookManager
     @tags = {}
 
     Dir.mkdir dir unless File.exists? dir
-
-    self.class.i_am_the_instance self
   end
 
   attr_reader :tags
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -26,7 +26,6 @@ class BaseIndex
   def initialize dir=BASE_DIR
     @dir = dir
     @lock = Lockfile.new lockfile, :retries => 0, :max_age => nil
-    self.class.i_am_the_instance self
   end
 
   def lockfile; File.join @dir, "lock" end
diff --git a/lib/sup/label.rb b/lib/sup/label.rb
@@ -22,8 +22,6 @@ class LabelManager
     @new_labels = {}
     @modified = false
     labels.each { |t| @labels[t] = true }
-
-    self.class.i_am_the_instance self
   end
 
   def new_label? l; @new_labels.include?(l) end
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -35,8 +35,6 @@ EOS
     @thread = nil
     @last_poll = nil
     @polling = false
-
-    self.class.i_am_the_instance self
   end
 
   def buffer
diff --git a/lib/sup/sent.rb b/lib/sup/sent.rb
@@ -8,7 +8,6 @@ class SentManager
   def initialize source_uri
     @source = nil
     @source_uri = source_uri
-    self.class.i_am_the_instance self
     Redwood::log "SentManager intialized with source uri: #@source_uri"
   end
 
diff --git a/lib/sup/source.rb b/lib/sup/source.rb
@@ -168,7 +168,6 @@ class SourceManager
     @sources = {}
     @sources_dirty = false
     @source_mutex = Monitor.new
-    self.class.i_am_the_instance self
   end
 
   def [](id)
diff --git a/lib/sup/suicide.rb b/lib/sup/suicide.rb
@@ -9,7 +9,6 @@ class SuicideManager
     @fn = fn
     @die = false
     @thread = nil
-    self.class.i_am_the_instance self
     FileUtils.rm_f @fn
   end
 
diff --git a/lib/sup/undo.rb b/lib/sup/undo.rb
@@ -12,7 +12,6 @@ class UndoManager
 
   def initialize
     @@actionlist = []
-    self.class.i_am_the_instance self
   end
 
   def register desc, *actions, &b
diff --git a/lib/sup/update.rb b/lib/sup/update.rb
@@ -16,7 +16,6 @@ class UpdateManager
 
   def initialize
     @targets = {}
-    self.class.i_am_the_instance self
   end
 
   def register o; @targets[o] = true; end
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -495,19 +495,20 @@ class Time
   end
 end
 
-## simple singleton module. far less complete and insane than the ruby
-## standard library one, but automatically forwards methods calls and
-## allows for constructors that take arguments.
+## simple singleton module. far less complete and insane than the ruby standard
+## library one, but it automatically forwards methods calls and allows for
+## constructors that take arguments.
 ##
-## You must have #initialize call "self.class.i_am_the_instance self"
-## at some point or everything will fail horribly.
+## classes that inherit this can define initialize. however, you cannot call
+## .new on the class. To get the instance of the class, call .instance;
+## to create the instance, call init.
 module Singleton
   module ClassMethods
     def instance; @instance; end
     def instantiated?; defined?(@instance) && !@instance.nil?; end
     def deinstantiate!; @instance = nil; end
     def method_missing meth, *a, &b
-      raise "no instance defined!" unless defined? @instance
+      raise "no #{name} instance defined in method call to #{meth}!" unless defined? @instance
 
       ## if we've been deinstantiated, just drop all calls. this is
       ## useful because threads that might be active during the
@@ -517,13 +518,14 @@ module Singleton
 
       @instance.send meth, *a, &b
     end
-    def i_am_the_instance o
+    def init *args
       raise "there can be only one! (instance)" if defined? @instance
-      @instance = o
+      @instance = new(*args)
     end
   end
 
   def self.included klass
+    klass.private_class_method :allocate, :new
     klass.extend ClassMethods
   end
 end