Class: Object

Inherits:
BasicObject
Defined in:
lib/epitools/minimal.rb,
lib/epitools/core_ext/object.rb,
lib/epitools/core_ext/truthiness.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.alias_class_method(dest, src) ⇒ Object

Slightly gross hack to add a class method.


102
103
104
# File 'lib/epitools/minimal.rb', line 102

def self.alias_class_method(dest, src)
  metaclass.send(:alias_method, dest, src)
end

.attrs(*names) ⇒ Object

Creates attr_accessors and an initialize method that accepts the attrs as arguments. (It's kinda like an inline version of Struct.new(*args))


55
56
57
58
59
60
61
62
# File 'lib/epitools/core_ext/object.rb', line 55

def self.attrs(*names)
  attr_accessor *names
  define_method :initialize do |*vals|
    names.zip(vals) do |name, val|
      instance_variable_set("@#{name}", val)
    end
  end
end

.enumerable(*meths) ⇒ Object

Turns block-accepting iterator methods (eg: each) into methods that return an Enumerator when they're called called without a block.

It can transform many methods at once (eg: `enumerable :each, :all_people`).

Example:

def lots_of_stuff
  @stuff.each { |thing| yield thing }
end

enumerable :lots_of_stuff

Now you can use it like an Enumerator: object.lots_of_stuff.with_index.sort.zip(99..1000)


122
123
124
125
126
127
128
129
130
131
132
# File 'lib/epitools/minimal.rb', line 122

def self.enumerable *meths
  meths.each do |meth|
    alias_method "#{meth}_without_enumerator", meth
    class_eval %{
      def #{meth}(*args, &block)
        return to_enum(#{meth.inspect}, *args, &block) unless block_given?
        #{meth}_without_enumerator(*args, &block)
      end
    }
  end
end

.using(*args) ⇒ Object

Return a copy of the class with modules mixed into it.


67
68
69
70
71
72
73
74
75
# File 'lib/epitools/core_ext/object.rb', line 67

def self.using(*args)
  if block_given?
    yield using(*args)
  else
    copy = self.dup
    args.each { |arg| copy.send(:include, arg) }
    copy
  end
end

Instance Method Details

#__DIR__(*args) ⇒ Object

This method is convenience for the `File.expand_path(File.dirname(__FILE__))` idiom. (taken from Michael Fellinger's Ramaze… thanx, dood! :D)


24
25
26
27
28
# File 'lib/epitools/minimal.rb', line 24

def __DIR__(*args)
  filename = caller[0][/^(.*):/, 1]
  dir = File.expand_path(File.dirname(filename))
  ::File.expand_path(::File.join(dir, *args.map{|a| a.to_s}))
end

#ancestorsObject


176
177
178
# File 'lib/epitools/minimal.rb', line 176

def ancestors
  self.class.ancestors
end

#autoreq(const, path = nil, &block) ⇒ Object

'autoreq' is a replacement for autoload that can load gems.

Usage:

autoreq :Constant, 'thing-to-require'
autoreq :Constant, 'thing-to-require'
autoreq :OtherConstant do
  gem 'somegem', '~> 1.2'
  require 'somegem'
end

42
43
44
45
46
47
48
49
50
# File 'lib/epitools/minimal.rb', line 42

def autoreq(const, path=nil, &block)
  raise "Error: autoreq must be supplied with a file to load, or a block." unless !!path ^ block_given?

  if block_given?
    Module.autoreqs[const] = block
  else
    Module.autoreqs[const] = path
  end
end

#bench(*args, &block) ⇒ Object

Quick and easy benchmark.

Examples:

bench { something }
bench(90000000) { something }
bench :fast => proc { fast_method }, :slow => proc { slow_method }

In Ruby 1.9:

bench fast: ->{ fast_method }, slow: ->{ slow_method }

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/epitools/core_ext/object.rb', line 137

def bench(*args, &block)

  # Shitty perl-esque hack to let the method take all the different kind of arguments.
  opts  = Hash === args.last ? args.pop : {}
  n     = args.first || 100

  if opts.any?

    raise "Error: Supply either a do/end block, or procs as options. Not both." if block_given?
    raise "Error: Options must be procs." unless opts.all? { |k, v| v.is_a?(Proc) }

    benchblock = proc do |bm|
      opts.each do |name, blk|
        bm.report(name.to_s) { n.times &blk }
      end
    end

  elsif block_given?

    benchblock = proc do |bm|
      bm.report { n.times &block }
    end

  else
    raise "Error: Must supply some code to benchmark."
  end

  puts "* Benchmarking #{n} iterations..."
  Benchmark.bmbm(&benchblock)
end

#class_def(name, &blk) ⇒ Object

Defines an instance method within a class


95
96
97
# File 'lib/epitools/minimal.rb', line 95

def class_def name, &blk
  class_eval { define_method name, &blk }
end

#del(x) ⇒ Object

Remove an object, method, constant, etc.


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/epitools/minimal.rb', line 55

def del(x)
  case x
    when String
      del(x.to_sym)
    when Class, Module
      Object.send(:remove_const, x.name)
    when Method
      x.owner.send(:undef_method, x.name)
    when Symbol
      if Object.const_get(x)
        Object.send(:remove_const, x)
      elsif method(x)
        undef_method x
      end
    else
      raise "Error: don't know how to 'del #{x.inspect}'"
  end
end

#dmsg(msg) ⇒ Object

Emit a quick debug message (only if $DEBUG is true)


102
103
104
105
106
107
108
109
110
111
# File 'lib/epitools/core_ext/object.rb', line 102

def dmsg(msg)
  if $DEBUG
    case msg
    when String
      puts msg
    else
      puts msg.inspect
    end
  end
end

#float?Boolean

Default “float?” behaviour.


12
# File 'lib/epitools/core_ext/truthiness.rb', line 12

def float?; false; end

#in?(enum) ⇒ Boolean

Instead of:

if cookie_jar.include? cookie

Now you can do:

if cookie.in? cookie_jar

141
142
143
# File 'lib/epitools/minimal.rb', line 141

def in?(enum)
  enum.include? self
end

#integer?Boolean

Default “integer?” behaviour.


7
# File 'lib/epitools/core_ext/truthiness.rb', line 7

def integer?; false; end

#localsObject

Return a hash of local variables in the caller's scope: :variable_name=>value


6
7
8
9
10
11
12
# File 'lib/epitools/core_ext/object.rb', line 6

def locals
  require 'binding_of_caller'
  caller = binding.of_caller(1)
  vars = caller.eval("local_variables").reject{|e| e[/^_/]}
  vals = caller.eval("[ #{vars.join(",")} ]")
  Hash[ vars.zip(vals) ]
end

#marshalObject Also known as: to_marshal

Serialize this object to a binary String, using Marshal.dump.


80
81
82
# File 'lib/epitools/core_ext/object.rb', line 80

def marshal
  Marshal.dump self
end

#meta_def(name, &blk) ⇒ Object

Adds methods to a metaclass


90
91
92
# File 'lib/epitools/minimal.rb', line 90

def meta_def name, &blk
  meta_eval { define_method name, &blk }
end

#meta_eval(&blk) ⇒ Object


85
86
87
# File 'lib/epitools/minimal.rb', line 85

def meta_eval &blk
  metaclass.instance_eval &blk
end

#notObject

Negates a boolean, chained-method style.

Example:

>> 10.even?
=> true
>> 10.not.even?
=> false

182
183
184
# File 'lib/epitools/core_ext/object.rb', line 182

def not
  NotWrapper.new(self)
end

#number?Boolean

Default “number?” behaviour.


17
# File 'lib/epitools/core_ext/truthiness.rb', line 17

def number?; false; end

#present?Boolean


168
169
170
# File 'lib/epitools/core_ext/object.rb', line 168

def present?
  true
end

#time(message = nil) ⇒ Object

Time a block.


116
117
118
119
120
121
122
123
124
# File 'lib/epitools/core_ext/object.rb', line 116

def time(message=nil)
  start = Time.now
  result = yield
  elapsed = Time.now - start

  print "[#{message}] " if message
  puts "elapsed time: %0.5fs" % elapsed
  result
end

#to_json(pretty = true) ⇒ Object

Serialize this object to JSON (defaults to “pretty” indented JSON).


95
96
97
# File 'lib/epitools/core_ext/object.rb', line 95

def to_json(pretty=true)
  pretty ? JSON::pretty_generate(self) : JSON.dump(self)
end

#to_yamlObject

Serialize this object to YAML.


88
89
90
# File 'lib/epitools/core_ext/object.rb', line 88

def to_yaml
  YAML::dump(self)
end

#truthy?Boolean

`truthy?` means `not blank?`


22
23
24
25
26
27
28
# File 'lib/epitools/core_ext/truthiness.rb', line 22

def truthy?
  if respond_to? :blank?
    not blank?
  else
    not nil?
  end
end

#try(method, *args, &block) ⇒ Object

Instead of:

@person ? @person.name : nil

Now you can do:

@person.try(:name)

157
158
159
# File 'lib/epitools/minimal.rb', line 157

def try(method, *args, &block)
  send(method, *args, &block) if respond_to? method
end

#with(options = {}) ⇒ Object

Gives you a copy of the object with its attributes changed to whatever was passed in the options hash.

Example:

>> cookie = Cookie.new(:size=>10, :chips=>200)
=> #<Cookie:0xffffffe @size=10, @chips=200>
>> cookie.with(:chips=>50)
=> #<Cookie:0xfffffff @size=10, @chips=50>

(All this method does is dup the object, then call “key=(value)” for each key/value in the options hash.)

BONUS FEATURE! ==

If you supply a block, it just gives you the object, and returns whatever your block returns.

Example:

>> {a: 10, b: 2}.with { |hash| hash[:a] / hash[:b] }
=> 5

Good for chaining lots of operations together in a REPL.


39
40
41
42
43
44
45
46
47
# File 'lib/epitools/core_ext/object.rb', line 39

def with(options={})
  if block_given?
    yield self
  else
    obj = dup
    options.each { |key, value| obj.send "#{key}=", value }
    obj
  end
end