GithubHelp home page GithubHelp logo

ruby-enum's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-enum's Issues

5 Test failures on Alpine Linux

Ruby version: ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux-musl]
ruby-enum version: 0.7.2

While building ruby-enum for Alpine Linux, the suite reports the following errors:

rspec ./spec/ruby-enum/enum_spec.rb:23 # Ruby::Enum raises UninitializedConstantError on an invalid constant
rspec ./spec/ruby-enum/enum_spec.rb:122 # Ruby::Enum on duplicate keys raises DuplicateKeyError
rspec ./spec/ruby-enum/enum_spec.rb:132 # Ruby::Enum on duplicate values raises a DuplicateValueError
rspec ./spec/ruby-enum/enum_spec.rb:145 # Ruby::Enum Given a class that has not defined any enums should raise Ruby::Enum::Errors::UninitializedConstantError
rspec ./spec/ruby-enum/enum_spec.rb:167 # Ruby::Enum Subclass behavior parent class should not have enums defined in child classes

See https://gist.github.com/Ikke/e9690849306977865e9df9f8598886a2 for the exceptions.

This might be due to the Ruby-i18n upgrade.

[Feature request] Add exhaustive case matcher

@dblock Thanks for making this gem! :)

One use case I have for enums is that I want to use them in case statements. A nice feature in Rust is exhaustive matching. Obviously, this doesn't work in native Ruby because of the missing types. However, in ruby-enum, it can work, because we have the information about which cases should be handled.

A possible drawback of this is that such a check adds additional steps to each call of the case statement and makes the runtime of the code slower.

I implemented a quick version of this in a project of mine and would be happy to contribute it to this project. A default/else block could be added as well.

Let me know what you think about it :)

##
# Adds a method to an enum class that allows for exhaustive matching on a value.
#
# @example
# class Color
#   include Ruby::Enum
#   include Ruby::Enum::Ecase
#
#   define :RED, :red
#   define :GREEN, :green
#   define :BLUE, :blue
# end
#
# Color.ecase(Color::RED, {
#   [Color::RED, Color::GREEN] => -> { puts "red or green" },
#   Color::BLUE => -> { puts "blue" },
# })
module Ruby::Enum::Ecase
  def self.included(klass)
    klass.extend(ClassMethods)
  end

  ##
  # @see Ruby::Enum::Ecase
  module ClassMethods
    class ValuesNotDefinedError < StandardError
    end
    class NotAllCasesHandledError < StandardError
    end

    def ecase(value, cases)
      validate_cases(cases)

      cases.each do |values, block|
        values = [values] unless values.is_a?(Array)
        block.call if values.include?(value)
      end
    end

    private

    def validate_cases(cases)
      all_values = cases.keys.flatten
      superfluous_values = all_values - values
      missing_values = values - all_values

      if superfluous_values.any?
        raise ValuesNotDefinedError, "Value(s) not defined: #{superfluous_values.join(", ")}"
      end
      if missing_values.any? # rubocop:disable Style/GuardClause
        raise NotAllCasesHandledError, "Not all cases handled: #{missing_values.join(", ")}"
      end
    end
  end
end

Purpose of parse() method?

From the documentation ("Attempts to parse an enumerated value"), I've been assuming the parse() method takes a value and returns the enum instance. I only discovered it didn't when I tried to use it with CONSTANT_CASE keys and CamelCase values:

require 'ruby-enum'

class Example
  include Ruby::Enum

  define :FOO, 'Foo'
  define :BAR, 'Bar'
  define :BAZ_QUX, 'BazQux'
  define :CORGE_GRAUPLY, 'CorgeGrauply'
end

Example.values.each do |v|
  parsed = Example.parse(v)
  puts "#{v} : #{parsed}"
end

# => Foo : Foo
# => Bar : Bar
# => BazQux : 
# => CorgeGrauply : 

I've created two patches, one that clarifies the documentation, and another that adds a method for_value() that does what I thought parse() did, as well as a corresponding for_key(). See what you think.

Value: default to key

Allow define to optionally accept a value.

If no value is given, the value will default to the key:

class A
  include Ruby::Enum
  define :X
end

A::X == :X

`values` class method does not read inherited enums

The values class method does not inherit the defined enum values from the parent class.

class A
  include Ruby::Enum
  define :X, 'X'
end

class B < A
  include Ruby::Enum
  define :Y, 'Y'
end

I would expect:

B.values() == [B::X, B::Y]

yet

B.values() == [B::Y]

Support subclassing an Enum

if it's supported: add some tests for it; if not: raise an error when trying to subclass, or when trying to call .define from the subclass

NameError: wrong constant name default on 0.7.1

Given a Gemfile like:

source 'https://rubygems.org/'

gem 'ruby-enum', '0.7.1'
gem 'rake'

And a Rakefile like:

task :go do
  require 'ruby-enum'

  class Parse
    include Ruby::Enum

    define :default, 0
    define :normalize, (1 << 8)
    define :validate_utf8, (1 << 9)
    define :smart, (1 << 10)
  end


  puts Parse.to_h[:smart]
end

Running rake go bombs on 0.7.1:

rake aborted!
NameError: wrong constant name default
/Users/gjtorikian/Desktop/foo/Rakefile:7:in `<class:Parse>'
/Users/gjtorikian/Desktop/foo/Rakefile:4:in `block in <top (required)>'
/Users/gjtorikian/.rbenv/versions/2.2.3/bin/bundle:23:in `load'
/Users/gjtorikian/.rbenv/versions/2.2.3/bin/bundle:23:in `<main>'
Tasks: TOP => go
(See full trace by running task with --trace)

Versions 0.7.0 and lower worked as expected, though.

Operator "enum&.value" require ruby 2.3.0

Hi,

this operator requires ruby 2.3.0

enum&.value

Using ruby 2.1.7 fails with an "unexpected error"

/home/.rvm/gems/ruby-2.1.7/gems/ruby-enum-0.8.0/lib/ruby-enum.rb:6:in 'require': /home/.rvm/gems/ruby-2.1.7/gems/ruby-enum-0.8.0/lib/ruby-enum/enum.rb:90: syntax error, unexpected '.' (SyntaxError)
        enum&.value
              ^
/home/.rvm/gems/ruby-2.1.7/gems/ruby-enum-0.8.0/lib/ruby-enum/enum.rb:111: syntax error, unexpected '.'
        enum&.key
              ^
              from /home/.rvm/gems/ruby-2.1.7/gems/ruby-enum-0.8.0/lib/ruby-enum.rb:6:in '<top (required)>'```

Replace interpolated shell command in ruby-enum.gemspec with a native Ruby construct.

While I'll admit it's a bit pedantic to zero in on such a minor aspect of the gem specification, I think it's important to minimize friction and implicit dependencies wherever possible in packages we write for other developers.

While it's very unlikely that a dev using Ruby isn't also using git, I think it's good practice to make as few assumptions
about a user's development environment as possible.

Here's the code in context:

https://github.com/dblock/ruby-enum/blob/master/ruby-enum.gemspec#L11

and here's my suggested change. I think it's a bit naïve, but I think it's is a step in the right direction:

From this:

s.files = `git ls-files`.split("\n")

To this:

s.files = Dir['*']

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.