Last active
August 29, 2015 14:00
-
-
Save duckinator/ea6d659a625d7a898152 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
module EvilClass | |
class << self | |
def has_been_evil? | |
@@has_been_evil = false | |
end | |
def make_ruby_cry | |
return unless File.expand_path($0) == File.expand_path(__FILE__) | |
load ARGV[0] | |
@@has_been_evil = true | |
end | |
def load_file(filename, wrap, full_filename) | |
unless full_filename && File.exist?(full_filename) | |
raise LoadError, "cannot load such file -- #{filename}" | |
end | |
rewrite_code(filename, wrap, File.open(filename).read) | |
end | |
def rewrite_code(filename, wrap, code) | |
#TODO: Make wrap=true do something. | |
# See massive HACK comment below as to how this was kept so | |
# simple, despite the fact that it should technically require | |
# parsing partially-invalid Ruby. | |
code.gsub!(/^(\s*)class ([^\s<]+)\s*(<\s*([^\s]))?$/, 'const_set :"\2", Class.new(\4) do') | |
# TODO: Check if TOPLEVEL_BINDING is actually correct. | |
eval(code, TOPLEVEL_BINDING, filename) | |
end | |
end | |
end | |
# const_set/const_get/const_missing/method_missing wizardry lovingly | |
# stolen from @wilkie: https://gist.github.com/wilkie/10cf0cf60f371f680d30 | |
module Kernel | |
def const_set(sym, value, &block) | |
# HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK | |
# | |
# We should be changing this: | |
# | |
# class X < Y | |
# ... | |
# end | |
# | |
# to: | |
# | |
# const_set(:"X", Class.new(const_get(:"Y")) { | |
# ... | |
# }) | |
# | |
# But, instead, we change it to this, so we don't have to actually | |
# parse Ruby, this way (we just match a single line): | |
# | |
# const_set :"X", Class.new(const_get(:"Y")) do | |
# ... | |
# end | |
# | |
# *This is actually passing the block to const_set.* | |
# The following if statement makes it behave as if that were not | |
# the case. | |
# | |
# HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK | |
if block | |
value.class_eval(&block) | |
return const_set(sym, value) | |
end | |
if sym.to_s.match /^[^A-Z]/ | |
@@__cool_constants ||= {} | |
@@__cool_constants[sym] = value | |
else | |
super(sym, value) | |
end | |
end | |
def const_get(sym) | |
if sym.to_s.match /^[^A-Z]/ | |
@@__cool_constants ||= {} | |
if @@__cool_constants.has_key? sym | |
return @@__cool_constants[sym] | |
end | |
end | |
super(sym) | |
end | |
def const_missing(sym, *args) | |
@@__cool_constants ||= {} | |
if @@__cool_constants.has_key? sym | |
@@__cool_constants[sym] | |
else | |
super(sym, *args) | |
end | |
end | |
def method_missing(sym, *args) | |
# "Real" Methods have precedence over unicode-constants which have | |
# precedence over dynamic methods. | |
@@__cool_constants ||= {} | |
if @@__cool_constants.has_key? sym | |
@@__cool_constants[sym] | |
else | |
super(sym, *args) | |
end | |
end | |
alias_method :original_load, :load | |
def load(filename, wrap=false) | |
EvilClass.load_file(filename, wrap, filename) | |
end | |
alias_method :original_require, :require | |
def require(filename) | |
full_filename = | |
if File.file?(filename) | |
filename | |
else | |
$:.lazy.map do |directory| | |
%w[rb so dll].lazy.map do |extension| | |
potential_filename = File.join(directory, "#{filename}.#{extension}") | |
potential_filename if File.exist?(potential_filename) | |
end.reject(&:nil?).first | |
end.reject(&:nil?).first | |
end | |
EvilClass.load_file(filename, false, full_filename) | |
$LOADED_FEATURES << File.expand_path(filename) | |
end | |
end | |
module EvilClass | |
make_ruby_cry unless has_been_evil? | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
..uckinator/evilclass⚡master+ ./test.rb | |
YEAAAAAAAAAAAAAAAAHHHHHHHHH | |
..uckinator/evilclass⚡master+ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!./evilclass.rb | |
require './❤.rb' | |
class 心 < ❤ | |
def w00t | |
puts yeah! | |
end | |
end | |
心.new.w00t |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ❤ | |
def yeah! | |
"YEAAAAAAAAAAAAAAAAHHHHHHHHH" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment