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.



105
106
107
# File 'lib/epitools/minimal.rb', line 105

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))



58
59
60
61
62
63
64
65
# File 'lib/epitools/core_ext/object.rb', line 58

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)



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/epitools/minimal.rb', line 125

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

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)



27
28
29
30
31
# File 'lib/epitools/minimal.rb', line 27

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



178
179
180
# File 'lib/epitools/minimal.rb', line 178

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


45
46
47
48
49
50
51
52
53
# File 'lib/epitools/minimal.rb', line 45

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 }


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/epitools/core_ext/object.rb', line 127

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



98
99
100
# File 'lib/epitools/minimal.rb', line 98

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

#del(x) ⇒ Object

Remove an object, method, constant, etc.



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

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)



92
93
94
95
96
97
98
99
100
101
# File 'lib/epitools/core_ext/object.rb', line 92

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

#float?Boolean

Default “float?” behaviour.

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


144
145
146
# File 'lib/epitools/minimal.rb', line 144

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

#integer?Boolean

Default “integer?” behaviour.

Returns:

  • (Boolean)


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.



70
71
72
# File 'lib/epitools/core_ext/object.rb', line 70

def marshal
  Marshal.dump self
end

#meta_def(name, &blk) ⇒ Object

Adds methods to a metaclass



93
94
95
# File 'lib/epitools/minimal.rb', line 93

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

#meta_eval(&blk) ⇒ Object



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

def meta_eval &blk
  metaclass.instance_eval &blk
end

#notObject

Negates a boolean, chained-method style.

Example:

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


172
173
174
# File 'lib/epitools/core_ext/object.rb', line 172

def not
  NotWrapper.new(self)
end

#number?Boolean

Default “number?” behaviour.

Returns:

  • (Boolean)


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

def number?; false; end

#present?Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/epitools/core_ext/object.rb', line 158

def present?
  true
end

#selfObject

Return this object. If given a block, yields this object and returns the result of the block.

eg: stuff.group_by(&:self)



170
171
172
173
174
175
176
# File 'lib/epitools/minimal.rb', line 170

def self 
  if block_given?
    yield self
  else
    self
  end
end

#time(message = nil) ⇒ Object

Time a block.



106
107
108
109
110
111
112
113
114
# File 'lib/epitools/core_ext/object.rb', line 106

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_bencodeObject

Serialize this object to a Python bencoded (pickled) string



179
180
181
# File 'lib/epitools/core_ext/object.rb', line 179

def to_bencode
  BEncode.dump(self)
end

#to_json(pretty = true) ⇒ Object

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



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

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

#to_yamlObject

Serialize this object to YAML.



78
79
80
# File 'lib/epitools/core_ext/object.rb', line 78

def to_yaml
  YAML::dump(self)
end

#truthy?Boolean

‘truthy?` means `not blank?`

Returns:

  • (Boolean)


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)


160
161
162
# File 'lib/epitools/minimal.rb', line 160

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.



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

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

#write_to(file) ⇒ Object



14
15
16
# File 'lib/epitools/core_ext/object.rb', line 14

def write_to(file)
  open(file, "wb") { |f| f.write self.to_s }
end