Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

extreme λ metaprogramming

Name: Anonymous 2012-08-04 2:56

please give me some help
i want to make this as meta/prog/ed as fuck


class Fixnum
  def seconds; self; end
  def minutes; seconds.send(:*,60); end
  def hours; minutes.send(:*,60); end
  def days; hours.send(:*,24); end
  def years; days.send(:*,365); end

  def ago; Time.now - self; end
  def from_now; Time.now + self; end

  def to_minutes; self / 60; end
  def to_hours; to_minutes / 60; end
  def to_days; to_hours / 24; end
  def to_years; to_days / 365; end


  def method_missing(method_id, *args)
    apply_calc = lambda do |op,unit|
      unit.send(op)
    end
    name = method_id.to_s
    if name =~ /^(second|minute|hour|day|year)$/
      apply_calc.(:*, name + 's')
      self.send(name + 's')
    else super
    end
  end
end

def days_old mybd = Time.new("1947-02-23 13:00:00 -0400")
  (Time.now - mybd).round.to_hours
end

delta = (1.minute.from_now - Time.now).round.to_hours
#to_hours shouldn't even be explicit it should be metaprogrammed with a new operator

Name: Anonymous 2012-08-04 2:58

obviously method_missing is missing some logic that fucks with the op based on if name =~ /^to/ .. apply_calc.(:/ .. but i couldn't even get the lambda working
Because I suck at japanese

Name: Anonymous 2012-08-04 3:29

retards, not every year is 365 days

>ruby

oh I didn't see that, carry on.

Name: Anonymous 2012-08-04 5:21

here you go op:
class Numeric
  class << self
  private
    # Doesn't bother with irregulars and is in no way complete besides.
    def _basic_pluralize(word)
      case word
      when /um$/
        "#{$`}a"
      when /is$/
        "#{$`}es"
      when /[aeiou]y$/
        "#{word}s"
      when /y$/
        "#{$`}ies"
      when /(?!ff|ffe)(.)(?:f|fe)$/
        "#{$`}#{$1}ves"
      when /(?:o|x|s|z|ch|sh)$/
        "#{word}es"
      else
        "#{word}s"
      end
    end
   
    # Notes:
    # - Using inspect to get a string from a data type that should evaluate to
    #   that data type though Ruby makes no guarantee of this. Would be better
    #   to define a new method just for this. Seeing as code isn't data and to
    #   avoid the translation to string then immediately back again it might be
    #   better to use a string in the first place, but once you go that far it
    #   makes sense to represent the calculation symbolicly, so that we might be
    #   able to compute the inverse function and not just hard code * and /.
    def define_unit(unit, spec = :self)
      units = _basic_pluralize(unit.to_s)
      if spec == :self
        class_eval(<<-end_ruby)
          def #{units}; self; end
          def to_#{units}; self; end
        end_ruby
      else
        class_eval(<<-end_ruby)
          def #{units}; #{spec[0].inspect} * #{spec[1]}; end
          def to_#{units}; to_#{spec[1]} / #{spec[0].inspect}; end
        end_ruby
      end
      alias_method(unit, units)
    end
  end
end

class Numeric
  define_unit :second
  define_unit :minute, [60, :seconds]
  define_unit :hour, [60, :minutes]
  define_unit :day, [24, :hours]
  define_unit :year, [365, :days]
 
  def ago; Time.now - seconds; end
  def from_now; Time.now + seconds; end
end

Name: Anonymous 2012-08-04 14:20

>>4
[ol]awesome supercool thanks that's some superb metainsight[/ol]

Don't change these.
Name: Email:
Entire Thread Thread List