<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,12 @@
+2007-04-12  Giuseppe Bilotta &lt;giuseppe.bilotta@gmail.com&gt;
+
+	* Basic class extensions: Module#define_structure() method. Syntax:
+		define_structure :SomeName, :attr_a, :attr_b
+	is equivalent to
+		SomeName = Struct.new(&quot;SomeName&quot;, :attr_a, :attr_b)
+	except that the new Struct is not created if it already exists and the
+	attributes list is the same.
+
 2007-03-31  Dmitry Kim &lt;dmitry.kim@gmail.com&gt;
 
 	* HttpUtil: major rework. get_response() method now respects
@@ -12,7 +21,7 @@
 	been removed (mostly because it won't play well with future HTTP
 	encodings support), please use get_partial() or get_request() instead.
 	* Utils: http_get() method has been removed (long obsoleted by
-        HttpUtil)
+	HttpUtil)
 	* different plugins: modified to accomodate for HttpUtil changes.
 
 2007-03-24  Giuseppe Bilotta &lt;giuseppe.bilotta@gmail.com&gt;</diff>
      <filename>ChangeLog</filename>
    </modified>
    <modified>
      <diff>@@ -32,10 +32,9 @@
 #   * fixed regexp usage in requirements for plugin map
 #   * add proper auth management
 
-OnJoinAction = Struct.new(&quot;OnJoinAction&quot;, :host, :action, :channel, :reason)
-BadWordAction = Struct.new(&quot;BadWordAction&quot;, :regexp, :action, :channel, :timer, :reason)
-WhitelistEntry = Struct.new(&quot;WhitelistEntry&quot;, :host, :channel)
-
+define_structure :OnJoinAction, :host, :action, :channel, :reason
+define_structure :BadWordAction, :regexp, :action, :channel, :timer, :reason
+define_structure :WhitelistEntry, :host, :channel
 
 class BansPlugin &lt; Plugin
 </diff>
      <filename>data/rbot/plugins/bans.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,10 +27,10 @@
 # TODO:: when Ruby 2.0 gets out, fix the FIXME 2.0 UTF-8 workarounds
 
 # Class for storing question/answer pairs
-QuizBundle = Struct.new( &quot;QuizBundle&quot;, :question, :answer )
+define_structure :QuizBundle, :question, :answer
 
 # Class for storing player stats
-PlayerStats = Struct.new( &quot;PlayerStats&quot;, :score, :jokers, :jokers_time )
+define_structure :PlayerStats, :score, :jokers, :jokers_time
 # Why do we still need jokers_time? //Firetech
 
 # Maximum number of jokers a player can gain</diff>
      <filename>data/rbot/plugins/games/quiz.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-RouletteHistory = Struct.new(&quot;RouletteHistory&quot;, :games, :shots, :deaths, :misses, :wins)
+define_structure :RouletteHistory, :games, :shots, :deaths, :misses, :wins
 
 class RoulettePlugin &lt; Plugin
   BotConfig.register BotConfigBooleanValue.new('roulette.autospin',</diff>
      <filename>data/rbot/plugins/games/roulette.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 # GB: Ok, we *really* need to switch to db for this plugin too
 
-Quote = Struct.new(&quot;Quote&quot;, :num, :date, :source, :quote)
+define_structure :Quote, :num, :date, :source, :quote
 
 class QuotePlugin &lt; Plugin
   def initialize</diff>
      <filename>data/rbot/plugins/quotes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,9 +13,7 @@
 # plugin. You can create them directly in an IRC channel, and invoke them just
 # like normal rbot plugins. 
 
-
-Command = Struct.new( &quot;Command&quot;, :code, :nick, :created, :channel )
-
+define_structure :Command, :code, :nick, :created, :channel
 
 class ScriptPlugin &lt; Plugin
 </diff>
      <filename>data/rbot/plugins/script.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Saw = Struct.new(&quot;Saw&quot;, :nick, :time, :type, :where, :message)
+define_structure :Saw, :nick, :time, :type, :where, :message
 
 class SeenPlugin &lt; Plugin
   def help(plugin, topic=&quot;&quot;)</diff>
      <filename>data/rbot/plugins/seen.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Url = Struct.new(&quot;Url&quot;, :channel, :nick, :time, :url, :info)
+define_structure :Url, :channel, :nick, :time, :url, :info
 
 class ::UrlLinkError &lt; RuntimeError
 end</diff>
      <filename>data/rbot/plugins/url.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,6 +13,30 @@
 # Please note that global symbols have to be prefixed by :: because this plugin
 # will be read into an anonymous module
 
+# Extensions to the Module class
+#
+class ::Module
+
+  # Many plugins define Struct objects to hold their data. On rescans, lots of
+  # warnings are echoed because of the redefinitions. Using this method solves
+  # the problem, by checking if the Struct already exists, and if it has the
+  # same attributes
+  #
+  def define_structure(name, *members)
+    sym = name.to_sym
+    if Struct.const_defined?(sym)
+      kl = Struct.const_get(sym)
+      if kl.new.members.map { |member| member.intern } == members.map
+        debug &quot;Struct #{sym} previously defined, skipping&quot;
+        const_set(sym, kl)
+        return
+      end
+    end
+    debug &quot;Defining struct #{sym} with members #{members.inspect}&quot;
+    const_set(sym, Struct.new(name.to_s, *members))
+  end
+end
+
 
 # Extensions to the Array class
 #</diff>
      <filename>lib/rbot/core/utils/extends.rb</filename>
    </modified>
    <modified>
      <diff>@@ -546,7 +546,6 @@ module ::Irc
       return retval
     end
 
-
   end
 end
 </diff>
      <filename>lib/rbot/core/utils/utils.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bf03d9f2b695772212abee81d405483c5c374633</id>
    </parent>
  </parents>
  <author>
    <name>Giuseppe Bilotta</name>
    <email>giuseppe.bilotta@gmail.com</email>
  </author>
  <url>http://github.com/jsn/rbot/commit/ac39a3b330cbf7c4b65ba907783364b63fb109b3</url>
  <id>ac39a3b330cbf7c4b65ba907783364b63fb109b3</id>
  <committed-date>2007-04-12T03:35:45-07:00</committed-date>
  <authored-date>2007-04-12T03:35:45-07:00</authored-date>
  <message>Module\#define_structure method: define a new Struct only if doesn't exist already or if the attribute list changed</message>
  <tree>e773d062644ecad55fcd0d48e505a882b0f94a82</tree>
  <committer>
    <name>Giuseppe Bilotta</name>
    <email>giuseppe.bilotta@gmail.com</email>
  </committer>
</commit>
