Project

rusty_key

0.0
No commit activity in last 3 years
No release in over 3 years
Replaces keywords with method calls. Not for serious use.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.0
~> 10.0
~> 3.0

Runtime

 Project Readme

rusty_key

This gem replaces many keywords with more-or-less equivalent method calls.

Why?

I made a joke about Rust's proposed "dot keyword" syntax, namely that they should apply it to all their keywords.

Then I took that joke too far.

I have nothing but respect for the Rust Lang Team's work, and their proposal regarding the await keyword makes perfect sense to me. This is just a well-intentioned goof.

Usage

Don't?

If you really want to, get it like this:

$ gem install rusty_key

Then start with this:

require 'rusty_key'

RustyKey.using

Below are some things you can do, but it's probably not an exhaustive list. Consider using braces rather than do and end to heighten the effect.

Define methods

:add_two.def { |x, y|
  x + y
}

add_two(3, 4) # => 7
:add_many.def { |*xs|
  xs.reduce(0, :+)
}

add_many(1, 1, 2, 3, 5, 8, 13) # => 33
:foo.def { |x, y, *zs, key: value, &block|
  # stuff
}

Define and monkey patch classes

:Dog.class {
  :initialize.def { |color|
    @color = color
  }

  :bark.def {
    "#{@color.capitalize} dog says: wruff!"
  }
}

Dog.new(:green).bark
# => "Green dog says: wruff!"

Define and monkey patch modules

:PrettyBow.module {
  # stuff
}

using, alias, include, extend

:RustyKey.using
:f.def { |x|
  # stuff
}
:func.alias :f
:String.class {
  :Cheese.include
  :Kite.extend
}

Flow control

computation = -> { expensive }
computation.if(necessary?)
  .else_if(cheap_check) { one_thing }
  .elsif(-> { expensive_check }) { another_thing }
  .else! { go_to_sleep }

Boolean logic

false.or { true } # => truthy
false.and { expensive } # => falsey
400.and { 20 } # => truthy

Case expressions

x.case
  .when(String) { "It's a string!" }
  .when(0..10) { "Pretty small..." }
  .when(-> y { y.respond_to? :phone }) { "Hello?" }
  .else { go_to_sleep } 

Raise and handle exceptions

# raises RuntimeError, like `raise "msg"`
"something's wrong!".raise
-> {
  ArgumentError.new("no arguing!").raise
}.rescue(OtherError, DifferentError) { |e|
  # not called
}.rescue(ArgumentError) { |e|
  puts "Please don't argue!"
}.rescue(Exception) { |e|
  # already caught, so this isn't called
}.rescue { |e|
  # would catch any uncaught StandardError
}.ensure! {
  puts "Thank you for following the rules."
}

return and yield

:f.def { |x|
  -> { x / 3 }.return_if(x > 10) # guard clause
  (x * 3).return # explicit return
}
:takes_block.def { |&block|
  25.yield # yields 25 to block
}

Caveats

  • Nested classes (and possibly other nested things) don't work.
  • There's no replacement for refine.
  • For #elsif/#else_if, wrap conditions in procs or they will always get evaluated.
  • Specifically the class Module can't be monkey patched this way, or at least it couldn't at some point. Haven't tested that in a while.
  • Speaking of which: There are no automated tests. I didn't think this would continue to the point where I might need them; I was wrong.
  • Use #return_if and #return_unless for conditional returns (e.g. guard clauses) unless you're very comfortable with the difference in semantics between regular procs and lambdas.

Acknowledgements

I'd like to thank:

  • John Mair, whose binding_of_caller gem, released under the MIT license, makes most of this possible.
  • The Rust Lang Team, who do great work and inspire terrible jokes.
  • Matz, who will hopefully not ban me from using Ruby for releasing this.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/molly-cactus/rusty. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Unlicense

This is free and unencumbered software released into the public domain.

Code of Conduct

Everyone interacting in the Rusty project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.