Ruby has Integer(...) and Float(...), but does it have Boolean(…) for things like:

Boolean(ENV[“SOME_FLAG”])

What's the Ruby idiom here?

Feature #20882: Provide Boolean(...) - Ruby master - Ruby Issue Tracking System

Redmine

@getajobmike we’ve had to roll our own version of this in the past — it’d be a welcome add to the language
@getajobmike maybe /\Atrue|0\z/.match?(value&.to_s)
@getajobmike !!ENV[“SOME_FLAG”]

@llimllib @getajobmike

001> ENV["FLAG"]
=> "false"
002> !!ENV["FLAG"]
=> true

@jandudulski @getajobmike Yup that’s how that works

@llimllib @getajobmike but it's not what you want to achieve :)

I use Dry::Types for this.

Dry.Types::Params::Bool[ENV["FLAG"]]

@getajobmike flip-flop? !!ENV[“flag”]
@getajobmike I’m not aware of anything built-in to Ruby, but there is ‘ActiveModel::Type::Boolean#cast’.

@floehopper @getajobmike yeah, if ruby provided it, I assume it'd look something like this.

https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html

ActiveRecord::Type::Boolean

Active Model Boolean Type A class that behaves like a boolean type, including rules for coercion of user input.

@getajobmike I want a built-in Boolean(). Others will probably recommend something like dry-types or something else that can map "true"/"false"/"yes"/"no"/"y"/"n" to true/false.
@getajobmike I usually do something like `%w(1 true yes).include?(ENV[“SOME_FLAG”].downcase)`

@getajobmike Nancy Sinatra it:

Bang bang (my baby shot me down)

@Schneems

irb(main):003> ENV["FOO"] = "0"
=> "0"
irb(main):004> !!ENV["FOO"]
=> true

Would you expect this behavior?

@getajobmike the most intuitive env var APIs for Ruby users are the ones that only check for presence rather than contents (imho) but I know some do what you’re describing

Unfortunately if you want to provide a default value for the env var (say, on Heroku) then there is no way to force unset a default config.

@Schneems @getajobmike if you want to validate more than just presence you could use this gem: https://github.com/fastruby/dotenv_validator 🤓
GitHub - fastruby/dotenv_validator: This gem check if required env variables are present and its format using the .env and .env.sample files from Dotenv.

This gem check if required env variables are present and its format using the .env and .env.sample files from Dotenv. - fastruby/dotenv_validator

GitHub

@getajobmike Just today I noticed this is how it works. In a Rails controller `request.xhr? # => 0` when true.

I think JS is, infamously, the only language where you'd expect `!!"0" == true`.

@Schneems

maybe_so/lib/maybe_so/core_ext at main · planningcenter/maybe_so

Ruby boolean type casting. Contribute to planningcenter/maybe_so development by creating an account on GitHub.

GitHub
@getajobmike @Schneems Well, no. But I would totally expect !!"0" to be true in Ruby. So maybe this is context-dependent and a generic Boolean() wouldn’t cut it.

@getajobmike The boolean gem seems to provide the ‘Boolean()’ method that you want:

https://github.com/ioquatix/boolean

GitHub - ioquatix/boolean: Useful methods for working with Booleans

Useful methods for working with Booleans. Contribute to ioquatix/boolean development by creating an account on GitHub.

GitHub

@getajobmike I have always used ENV["SOME_FLAG”] == "true”

I am definitely Team I Don’t Like 78 Forms of Boolean Representation, so anything other than the string "true" is considered false to me.

But I would love to see a Boolean data type and coercion method to address this issue from stdlib

@davetron5000 @getajobmike

["1", "y", "yes", "true"].include?(ENV["FLAG"].to_s.downcase ) 🙃

And of course for the opposite:

["0", "n", "no", "false"].include?(ENV["FLAG"].to_s.downcase)

@caleb @getajobmike I’m not a fan of bang bang because empty string should be treated as false
@caleb @getajobmike (to be clear, only empty string from Env vars should be false. Definitely don’t think empty should be false generally in Ruby. But vars coming from Shell, empty is treated equivalent to unset )
@jasonkarns @getajobmike I was being a bit cheeky. Double negation isn’t a good solution for ENV.
@getajobmike rails has some private API array of falsey values that it uses to cast query params.
It does […].include?(ENV[…]) but that array would be a good start to the right values for a Boolean() to check.
@getajobmike for env vars in particular, !ENV.fetch("MIKE_IS_RAD", "").empty? but that's gross and isn't general enough for a Boolean(...)

@jc00ke @getajobmike Since ENV isn't a hash, it could theoretically specialize on string formats like this, letting it return numbers or booleans.

FLAG=true SIDEKIQ_WORKERS=5

ENV.boolean("FLAG") # => true
ENV.boolean("UNSET_FLAG") # => nil
ENV.integer("SIDEKIQ_WORKERS") # => 5

https://gist.github.com/jgaskins/de1f724e980ce29e31ac90eb2b5bab1f

Type coercion for ENV

Type coercion for ENV. GitHub Gist: instantly share code, notes, and snippets.

Gist
@getajobmike I’m also a big fan of Array()
@veganstraightedge @getajobmike don’t forget String(), which I really like
@stevenharman @getajobmike those Kernel methods are a real swell lineup 🎉
@veganstraightedge @getajobmike Array() has caught me out a few times with Array(Time.now). Hence I always rely on Array.wrap when ActiveSupport land.