Skip to content

Instantly share code, notes, and snippets.

@rentalcustard
Last active January 13, 2022 14:21
Show Gist options
  • Save rentalcustard/5524668 to your computer and use it in GitHub Desktop.
Save rentalcustard/5524668 to your computer and use it in GitHub Desktop.
Removing all literals from Ruby

Literals are ugly. Let's remove them.

True/false:

2.0.0p0 :001 > !Date
=> false
2.0.0p0 :002 > require Date.to_s.downcase
=> true

Integers and floats:

2.0.0p0 :003 > Date.civil.year
=> -4712 
2.0.0p0 :004 > Date.civil.year.to_f
=> -4712.0
#and the others are left as an exercise for the reader

Hashes:

2.0.0p0 :005 > Date._jisx0301(self.methods.first.to_s)
=> {}

Arrays:

2.0.0p0 :006 > Array(Date._jisx0301(self.methods.first.to_s))
=> []

Nil:

2.0.0p0 :007 > Date._jisx0301(self.methods.first.to_s).default_proc
=> nil    

Strings/symbols:

2.0.0p0 :008 > method(:using).inspect[(Date.civil.year - Date.civil.year).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ]
=> "a"
2.0.0p0 :009 > method(:using).inspect[(Date.civil.year - Date.civil.year).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ].succ
=> "b" 
2.0.0p0 :010 > method(:using).inspect[(Date.civil.year - Date.civil.year).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ].to_sym
=> :a
#and the others are left as an exercise for the reader

Ranges:

2.0.0p0 :011 > ObjectSpace.each_object(eval method(:extend).inspect[(Date.civil.year.-(Date.civil.year)).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ].upcase + method(:include).inspect[(Date.civil.year.-(Date.civil.year)).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ] +  method(:extend).inspect[(Date.civil.year.-(Date.civil.year)).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ] + method(:include).inspect[(Date.civil.year.-(Date.civil.year)).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ].succ.succ.succ.succ.succ.succ + method(:include).inspect[(Date.civil.year.-(Date.civil.year)).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ].succ.succ.succ.succ).map.first
=> 1..-1

Unfortunately, ranges aren't mutable. I guess you could construct a string and eval it.

Lambdas:

#trivial, but let's do it anyway
2.0.0p0 :011 > def add_to_self(a); a + a; end
=> nil
2.0.0p0 :012 > method(:add_to_self).to_proc[Date.civil.year.denominator]
=> 2

Regexen:

#trivial, but let's do it anyway
2.0.0p0 :013 > Regexp.compile(method(:using).inspect[(Date.civil.year - Date.civil.year).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ]) =~ "abc"
=> 0
@rentalcustard
Copy link
Author

Looking for creative suggestions for removing all symbol and string literals.

@rentalcustard
Copy link
Author

Sorted

@dbussink
Copy link

dbussink commented May 6, 2013

Since when is 11 not a literal? :)

@rentalcustard
Copy link
Author

So there's this other language called rubinius. It's weird.

~> irb
rubinius-2.0.0.rc1 :001 > method(:using).owner.methods.include?(:using)
NameError: undefined method `using' for main
   from Kernel(Object)#method at kernel/common/kernel18.rb:169
   from { } in Object#irb_binding at (irb):1
   from Rubinius::BlockEnvironment#call_on_instance at kernel/common/block_environment.rb:57
rubinius-2.0.0.rc1 :002 > method(:include).owner.methods.include?(:using)
 => false
rubinius-2.0.0.rc1 :003 > method(:include).owner.methods.include?(:include)
 => false
rubinius-2.0.0.rc1 :004 > require 'date'
 => true
rubinius-2.0.0.rc1 :005 > Date.civil.year
 => -4712
rubinius-2.0.0.rc1 :006 > Date.civil.year.to_f
 => -4712.0
rubinius-2.0.0.rc1 :007 >  Date._jisx0301(self.methods.first.to_s)
NoMethodError: undefined method `_jisx0301' on Date (Class)
   from Kernel(Class)#_jisx0301 (method_missing) at kernel/delta/kernel.rb:81
   from { } in Object#irb_binding at (irb):7
   from Rubinius::BlockEnvironment#call_on_instance at kernel/common/block_environment.rb:57
rubinius-2.0.0.rc1 :008 > method(:include).inspect[11]
 => 98
rubinius-2.0.0.rc1 :009 > method(:include).inspect
 => "#<Method: Object#include (defined in #<Class:#<Object:0x18a8>> at kernel/common/main.rb:4)>"
rubinius-2.0.0.rc1 :010 > method(:include).inspect[0]
 => 35
rubinius-2.0.0.rc1 :011 > method(:include).inspect[0].to_s
 => "35"
rubinius-2.0.0.rc1 :012 > method(:include).inspect.first
 => "#<Method: Object#include (defined in #<Class:#<Object:0x18a8>> at kernel/common/main.rb:4)>"
rubinius-2.0.0.rc1 :013 > method(:include).inspect.chars[11]

@rentalcustard
Copy link
Author

@dbussink good point! Fixed.

@rentalcustard
Copy link
Author

I'm trying to remove the string literal "date". Current progress:

2.0.0p0 :010 > ((method(:using).owner.methods.grep(:using).size)..71503).to_a.inject(method(:using).inspect[(Date.civil.year - Date.civil.year).succ.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ]) {|memo, _| memo.succ}
 => "date"

@rentalcustard
Copy link
Author

Ah, it was so simple!

@rentalcustard
Copy link
Author

Rubinius.

rubinius-2.0.0.rc1 :001 > require Date.to_s.downcase
NameError: Missing or uninitialized constant: Date
   from Module(Class)#const_missing at kernel/common/module.rb:438
   from { } in Object#irb_binding at (irb):1
   from Rubinius::BlockEnvironment#call_on_instance at kernel/common/block_environment.rb:57

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment