Sha256: 5987acfaee21d7b531120055ecd2456b6338f94c9062c724528e596c00c672af

Contents?: true

Size: 1.38 KB

Versions: 4

Compression:

Stored size: 1.38 KB

Contents

# define a module with a class method
module M
  def self.f
    puts 'success!'
  end

  def self.h
    puts 'and again!'
  end
end

# this allows it be invoked via
M.f

# but now we want to make it available globally
#
# [1]: http://softwarebyjosh.com/2012/01/21/Pirating-Ruby-Methods-For-Fun-And-Profit.html
# [2]: http://stackoverflow.com/questions/4390329/how-do-we-copy-singleton-methods-between-different-ruby-classes
# [3]: http://stackoverflow.com/questions/3782026/how-do-i-dynamically-define-a-method-as-private

main = self
# pirate = main.class.new.extend(M)
M.singleton_methods.each do |name|
  # main.class.send(:define_method, name, &M.method(name))
  Object.instance_eval do 
    define_method name, &M.method(name)
    private name
  end
  # M.method(name).unbind.bind(main)
end

# now, will this work?
f
# after much fiddling, it seems so

# however, we should not be able to invoke f on an `Object` instance
begin
  Object.new.f
rescue NoMethodError => e
  puts "success! failed to call `Object.new.f` with: #{ e }"
end

# this matches behavoir when defining on the top-level
def g
  puts 'blah'
end
begin
  Object.new.g
rescue NoMethodError => e
  puts "success! failed to call `Object.new.g` with: #{ e }"
end

# note that we can use this to fuck up methods on `Object`:
def to_s
  "hey!"
end
class C; end
begin
  C.new.to_s
rescue NoMethodError => e
  puts "fuck, we broke `Object.to_s`"
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
nrser-rash-0.2.3 dev/scratch/pirating_methods.rb
nrser-rash-0.2.2 dev/scratch/pirating_methods.rb
nrser-rash-0.2.1 dev/scratch/pirating_methods.rb
nrser-rash-0.2.0 dev/scratch/pirating_methods.rb