Module: Card::Set

Defined in:
lib/card/set.rb

Overview

remove_const :Set if const_defined?(:Set, false)

Defined Under Namespace

Modules: Format

Constant Summary collapse

@@modules =
{ :base=>[], :base_format=>{}, :nonbase=>{}, :nonbase_format=>{} }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clean_empty_module_from_hash(hash) ⇒ Object



323
324
325
326
327
328
# File 'lib/card/set.rb', line 323

def clean_empty_module_from_hash hash
  hash.each do |mod_name, modlist|
    modlist.delete_if { |x| x.instance_methods.empty? }
    hash.delete mod_name if modlist.empty?
  end
end

.clean_empty_modulesObject



316
317
318
319
320
321
# File 'lib/card/set.rb', line 316

def clean_empty_modules
  clean_empty_module_from_hash modules[ :nonbase ]
  modules[ :nonbase_format ].values.each do |hash|
    clean_empty_module_from_hash hash
  end
end

.extended(mod) ⇒ Object

each set file calls ‘extend Card::Set` when loaded



253
254
255
# File 'lib/card/set.rb', line 253

def extended mod
  register_set mod
end

.process_base_module_list(list, klass) ⇒ Object



305
306
307
308
309
310
311
312
313
314
# File 'lib/card/set.rb', line 305

def process_base_module_list list, klass
  list.each do |mod|
    if mod.instance_methods.any?
      klass.send :include, mod
    end
    if class_methods = mod.const_get_if_defined( :ClassMethods )
      klass.send :extend, class_methods
    end
  end
end

.process_base_modulesObject

“base modules” are modules that are permanently included on the Card or Format class “nonbase modules” are included dynamically on singleton_classes



296
297
298
299
300
301
302
303
# File 'lib/card/set.rb', line 296

def process_base_modules
  process_base_module_list modules[:base], Card
  modules[:base_format].each do |format_class, modules_list|
    process_base_module_list modules_list, format_class
  end
  modules.delete :base
  modules.delete :base_format
end

.register_set(set_module) ⇒ Object



257
258
259
260
261
262
263
264
# File 'lib/card/set.rb', line 257

def register_set set_module
  if set_module.all_set?
    modules[ :base ] << set_module
  else
    modules[ :nonbase ][ set_module.shortname ] ||= []
    modules[ :nonbase ][ set_module.shortname ] << set_module
  end
end

.write_tmp_file(set_pattern, anchors, from_file, seq) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/card/set.rb', line 266

def write_tmp_file set_pattern, anchors, from_file, seq
  # FIXME - this does not properly handle anchorless sets
  # There are special hacks for *all, but others (like *rstar) will not be found by
  # include_set_modules, which will look for Card::Set::Rstar, not Card::Set::Rstar::Blah
  # This issue appears to be addressed by making the entries, in modules arrays.
  # If yes remove this comment.

  to_file = "#{Cardio.paths['tmp/set'].first}/#{set_pattern}/#{seq}-#{anchors * '-'}.rb"
  anchor_modules = anchors.map { |a| "module #{a.camelize};" } * ' '
  file_content = <<EOF
# -*- encoding : utf-8 -*-
class Card; module Set; module #{set_pattern.camelize}; #{anchor_modules}
extend Card::Set
# ~~~~~~~~~~~ above autogenerated; below pulled from #{from_file} ~~~~~~~~~~~

#{ File.read from_file }

# ~~~~~~~~~~~ below autogenerated; above pulled from #{from_file} ~~~~~~~~~~~
end;end;end;#{'end;'*anchors.size}
EOF
  File.write to_file, file_content
  to_file
end

Instance Method Details

#all_set?Boolean

Returns:

  • (Boolean)


353
354
355
# File 'lib/card/set.rb', line 353

def all_set?
  name =~ /^Card::Set::All::/
end

#card_accessor(*args) ⇒ Object

ActiveCard support: accessing plus cards as attributes



223
224
225
226
# File 'lib/card/set.rb', line 223

def card_accessor *args
  options = args.extract_options!
  add_traits args, options.merge( :reader=>true, :writer=>true )
end

#card_reader(*args) ⇒ Object



228
229
230
231
# File 'lib/card/set.rb', line 228

def card_reader *args
  options = args.extract_options!
  add_traits args, options.merge( :reader=>true )
end

#card_writer(*args) ⇒ Object



233
234
235
236
# File 'lib/card/set.rb', line 233

def card_writer *args
  options = args.extract_options!
  add_traits args, options.merge( :writer=>true )
end

#define_active_job(name, final_method, queue = :default) ⇒ Object

creates an Active Job. The scheduled job gets the card object as argument and all serializable attributes of the card. (when the job is executed ActiveJob fetches the card from the database so all attributes get lost)

Parameters:

  • name (String)

    the name for the ActiveJob child class

  • final_method (String)

    the name of the card instance method to be queued

  • queue (Hash) (defaults to: :default)

    a customizable set of options

Options Hash (queue):

  • (:default) (Symbol)

    the name of the queue



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/card/set.rb', line 200

def define_active_job name, final_method, queue = :default
  class_name = name.to_s.camelize
  eval %{
    class ::#{class_name} < ActiveJob::Base
      queue_as #{queue}
    end
  }
  Object.const_get(class_name).class_eval do
   define_method :perform, proc { |card, attributes|
      attributes.each do |name, args|
        # symbols are not allowed so all symbols arrive here as strings
        # convert strings that were symbols before back to symbols
        value = args[:symbol] ? args[:value].to_sym : args[:value]
        card.instance_variable_set("@#{name}", value )
      end
      card.send final_method
  }
  end
end

#define_event_method(event, call_method, opts) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/card/set.rb', line 181

def define_event_method event, call_method, opts
  class_eval do
    define_method event do
      run_callbacks event do
        Card.with_logging :event, :message=>event, :context=>self.name, :details=>opts do
          send call_method
        end
      end
    end
  end
end

#define_event_perform_later_method(event, method_name) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/card/set.rb', line 164

def define_event_perform_later_method event, method_name
  class_eval do
    define_method method_name, proc {
      s_attr = self.serializable_attributes.each_with_object({}) do |name, hash|
               value = self.instance_variable_get("@#{name}")
               hash[name] =
                 if Symbol === value  # ActiveJob doesn't accept symbols as arguments
                   { :value => value.to_s, :symbol => true }
                 else
                   { :value => value }
                 end
            end
      Object.const_get(event.to_s.camelize).perform_later(self, s_attr)
    }
  end
end

#define_on_format(format_name = :base, &block) ⇒ Object



124
125
126
127
128
129
130
131
132
133
# File 'lib/card/set.rb', line 124

def define_on_format format_name=:base, &block
  klass = Card::Format.format_class_name format_name   # format class name, eg. HtmlFormat
  mod = const_get_or_set klass do                      # called on current set module, eg Card::Set::Type::Pointer
    m = Module.new                                     # yielding set format module, eg Card::Set::Type::Pointer::HtmlFormat
    register_set_format Card.const_get(klass), m
    m.extend Card::Set::Format
    m
  end
  mod.class_eval &block
end

#event(event, opts = {}, &final) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/card/set.rb', line 142

def event event, opts={}, &final
  perform_later =  (opts[:before] == :subsequent) || (opts[:after] == :subsequent)
  final_method = "#{event}_without_callbacks" #should be private?
  opts[:on] = [:create, :update ] if opts[:on] == :save

  Card.define_callbacks event

  class_eval do
    define_method final_method, &final
  end

  if perform_later
    defer_method = "#{event}_perform_later"
    define_event_perform_later_method event, defer_method
    define_active_job event, final_method, opts[:queue_as]
    define_event_method event, defer_method, opts
  else
    define_event_method event, final_method, opts
  end
  set_event_callbacks event, opts
end

#format(*format_names, &block) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/card/set.rb', line 113

def format *format_names, &block
  if format_names.empty?
    format_names = [:base]
  elsif format_names.first == :all
    format_names = Card::Format.registered.reject {|f| Card::Format.aliases[f]}
  end
  format_names.each do |f|
    define_on_format f, &block
  end
end

#register_set_format(format_class, mod) ⇒ Object



333
334
335
336
337
338
339
340
341
342
# File 'lib/card/set.rb', line 333

def register_set_format format_class, mod
  if self.all_set?
    modules[ :base_format ][ format_class ] ||= []
    modules[ :base_format ][ format_class ] << mod
  else
    format_hash = modules[ :nonbase_format ][ format_class ] ||= {}
    format_hash[ shortname ] ||= []
    format_hash[ shortname ] << mod
  end
end

#shortnameObject



344
345
346
347
348
349
350
351
# File 'lib/card/set.rb', line 344

def shortname
  parts = name.split '::'
  first = 2 # shortname eliminates Card::Set
  set_class = Card::SetPattern.find parts[first].underscore

  last = first + set_class.anchor_parts_count
  parts[first..last].join '::'
end

#view(*args, &block) ⇒ Object



135
136
137
138
139
# File 'lib/card/set.rb', line 135

def view *args, &block
  format do
    view *args, &block
  end
end