Skip to content

Instantly share code, notes, and snippets.

@Ravenstine
Last active April 1, 2016 23:20
Show Gist options
  • Save Ravenstine/423032cd2d36a24b86e3eda3b5dab6c5 to your computer and use it in GitHub Desktop.
Save Ravenstine/423032cd2d36a24b86e3eda3b5dab6c5 to your computer and use it in GitHub Desktop.
Ruby Snippets

Ruby Snippets

Sometimes, you don't need a gem for it.

This is a list of useful "snippets" for Ruby that are small but provide a lot of power. Copy them, modify them, and make them your own!

Snippets

Auto-assign Arguments to Instance Variables

If you have a class where you are assigning all your arguments to variables, and you plan on adding more arguments over time, this will accomplish that in one line as opposed to having to hard-code your assignments. Default argument values will get assigned unless a different value has been passed.

method(__method__).parameters.each{|p| instance_variable_set("@#{p[1]}", binding.local_variable_get(p[1]))}

Example use:

  class Model
    def initialize guid: SecureRandom.uuid, name: 'untitled', metadata: {}, precedence: 0, created_at:Time.now, enabled: false
      method(__method__).parameters.each{|p| instance_variable_set("@#{p[1]}", binding.local_variable_get(p[1]))}
    end
  end

One way to take this further would be to modify the snippet to also create attr_accessors!

Behavior Based on Stack Level

You may stumble on a circumstance where you need to call a method that invokes the same method bound to another object. In my experience, this can happen when a method is called between objects that are bi-directionally related. This can cause infinite recursion(i.e. Stack Level Too Deep), which is baaaaaad. Sometimes, especially if you are building a deep hash structure, it may be okay if the deeper objects don't return anything from said method in order to prevent recursion.

def related_objects
  return [] if stack_level_to_deep?(__method__)
  # ... routine that returns objects that are related to the current one,
  # whilst calling #related_objects on each of them, which would return this
  # object and call this same method again!
end
private
def stack_level_too_deep? name
  stack_level = caller.select{|s| s.include?("`related_objects'")}.count
  stack_level > 2
end

The stack_level_too_deep? method returns a boolean depending on if the specified method has been called more than twice. That way, you won't get related_objects deeper than 2 levels. related_objects uses that method to return an empty array if it returns true. This solution assumes that you aren't going to need related content on objects deeper than that number of levels.

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