defined_true? monkeypatch

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:

···

--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

Hi Sean,

"but this doesn't get us all the way" ... what doesn't defined? cover?

Jeremy Wood

···

On 9/9/20 1:27 PM, Sean Felipe Wolfe wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be *only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us all the way. So I'm considering monkeypatching Object like so:

classObject

defdefined_true?(const)

begin

returneval(const) == true

rescueNameError

returnfalse

end

end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if he is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Why not use an environment variable?

Or if you really must, a global variable.

···

On Wed, 9 Sep 2020, 19:27 Sean Felipe Wolfe, <ether.joe@gmail.com> wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

It is not entirely clear what you're doing, but avoid `eval`, there's
plenty of stdlib reflection that can help you here.

If I understand correctly, what you actually want is closer to:

Object.const_defined?(const) && Object.const_get(const) == true

···

On Wed, Sep 9, 2020 at 2:36 PM Jeremy Wood <jwood@pearlcomm.com> wrote:

Hi Sean,

"but this doesn't get us all the way" ... what doesn't defined? cover?

Jeremy Wood
On 9/9/20 1:27 PM, Sean Felipe Wolfe wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe> <ruby-talk-request@ruby-lang.org?subject=unsubscribe><http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
*Kevin D. Deisz*
Staff Production Engineer
Shopify <https://www.shopify.com/>

Hello Jeremy,

So I'm trying to avoid code like this:

#TEST_MODE=true
TEST_MODE=false

if I have TEST_MODE=false and use only defined? TEST_MODE, then I get a
true / non-false response from defined ?

I would like to say *only* TEST_MODE=true, or be able to delete the
reference entirely.

···

On Wed, Sep 9, 2020 at 11:36 AM Jeremy Wood <jwood@pearlcomm.com> wrote:

Hi Sean,

"but this doesn't get us all the way" ... what doesn't defined? cover?

Jeremy Wood
On 9/9/20 1:27 PM, Sean Felipe Wolfe wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe> <ruby-talk-request@ruby-lang.org?subject=unsubscribe><http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

That looks like it could work also. I didn't think about using the &&
operator. I would rather have something like defined_true? in my code
though rather than the && chain.

I'll dig a bit deeper to see what I can use instead of eval. Thanks Kevin ~~

···

On Wed, Sep 9, 2020 at 11:48 AM Kevin Deisz <kevin.deisz@gmail.com> wrote:

It is not entirely clear what you're doing, but avoid `eval`, there's
plenty of stdlib reflection that can help you here.

If I understand correctly, what you actually want is closer to:

Object.const_defined?(const) && Object.const_get(const) == true

On Wed, Sep 9, 2020 at 2:36 PM Jeremy Wood <jwood@pearlcomm.com> wrote:

Hi Sean,

"but this doesn't get us all the way" ... what doesn't defined? cover?

Jeremy Wood
On 9/9/20 1:27 PM, Sean Felipe Wolfe wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if
he is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe> <ruby-talk-request@ruby-lang.org?subject=unsubscribe><http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
*Kevin D. Deisz*
Staff Production Engineer
Shopify <https://www.shopify.com/>

--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

I could, but I'm really looking for syntactic sugar here for aesthetic
reasons, "beautiful code" reasons. Less characters, less to type, less
symbol characters.

Now if I just add defined_true? to my syntax highlighting I think that gets
me over :slight_smile:

···

On Wed, Sep 9, 2020 at 11:48 AM Tom Lord <lord.thom@gmail.com> wrote:

Why not use an environment variable?

Or if you really must, a global variable.

On Wed, 9 Sep 2020, 19:27 Sean Felipe Wolfe, <ether.joe@gmail.com> wrote:

Hello Rubyists, I've been working with this scenario:

* I want to set a constant to true to enable test mode
* otherwise, if the constant does not appear, enable normal mode

Rather than have TEST_MODE=true and TEST_MODE=off, I want there to be
*only* TEST_MODE=true, or nothing at all.

The closest thing i can find is Object.defined? , but this doesn't get us
all the way. So I'm considering monkeypatching Object like so:

class Object

  def defined_true?(const)

    begin

      return eval(const) == true

    rescue NameError

      return false

    end

  end

end

Any thoughts ? Thanks :slight_smile:
--
A musician must make music, an artist must paint, a poet must write, if
he is to be ultimately at peace with himself.
- Abraham Maslow

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
A musician must make music, an artist must paint, a poet must write, if he
is to be ultimately at peace with himself.
- Abraham Maslow

Sean,

Please forgive me if I am misunderstanding something.

In the event that TEST_MODE is undefined #defined? returns nil, which evaluates to false. In the case,

that TEST_MODE is defined #defined returns true. So you should be able to delete the value just fine. The only adjustment I see is that your check code would need to look like:

if(defined?(TEST_MODE) and TEST_MODE)

#do test code

else

#do production code

end

Here is demo script:

def check_debug_mode if(defined?(DEBUG_MODE))
     puts"Yup" else puts"Nope" end end #first check - nothing defined check_debug_mode

DEBUG_MODE=true #second check - debug set check_debug_mode

#third check - DEBUG_MODE=nil # this will give a warning for redefining a constant, but other than that shouldn't effect the results DEBUG_MODE=nil check_debug_mode

Jeremy Wood

···

On 9/9/20 2:01 PM, Sean Felipe Wolfe wrote:

Hello Jeremy,

So I'm trying to avoid code like this:

#TEST_MODE=true
TEST_MODE=false

if I have TEST_MODE=false and use only defined? TEST_MODE, then I get a true / non-false response from defined ?

I would like to say *only* TEST_MODE=true, or be able to delete the reference entirely.

On Wed, Sep 9, 2020 at 11:36 AM Jeremy Wood <jwood@pearlcomm.com > <mailto:jwood@pearlcomm.com>> wrote:

    Hi Sean,

    "but this doesn't get us all the way" ... what doesn't defined?
    cover?

    Jeremy Wood

    On 9/9/20 1:27 PM, Sean Felipe Wolfe wrote:

    Hello Rubyists, I've been working with this scenario:

    * I want to set a constant to true to enable test mode
    * otherwise, if the constant does not appear, enable normal mode

    Rather than have TEST_MODE=true and TEST_MODE=off, I want there
    to be *only* TEST_MODE=true, or nothing at all.

    The closest thing i can find is Object.defined? , but this
    doesn't get us all the way. So I'm considering
    monkeypatching Object like so:

    classObject

    defdefined_true?(const)

    begin

    returneval(const) == true

    rescueNameError

    returnfalse

    end

    end

    end

    Any thoughts ? Thanks :slight_smile:
    -- A musician must make music, an artist must paint, a poet must
    write, if he is to be ultimately at peace with himself.
    - Abraham Maslow

    Unsubscribe:<mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe> <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
    <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

--
A musician must make music, an artist must paint, a poet must write, if he is to be ultimately at peace with himself.
- Abraham Maslow

Ah, yes, what I didn't mention at the beginning. I am looking to do this
for potentially multiple constants. Trying to simplify the problem to
communicate it better to the group and ... oversimplified.

As I think the problem through though ... these test parameters are
actually going to potentially be on or off depending on parameters we call
the server with. So, having a single constant evaluated once upon startup
doesn't work anyhow. I guess I'll have to use a variable.

Thanks everyone for your input, at least I learned a bit more about
monkeypatching :slight_smile:

···

On Wed, Sep 9, 2020 at 12:10 PM Jeremy Wood <jwood@pearlcomm.com> wrote:

Sean,

Please forgive me if I am misunderstanding something.

In the event that TEST_MODE is undefined #defined? returns nil, which
evaluates to false. In the case,

that TEST_MODE is defined #defined returns true. So you should be able to
delete the value just fine. The only adjustment I see is that your check
code would need to look like:

if(defined?(TEST_MODE) and TEST_MODE)

  #do test code

else

  #do production code

end

Here is demo script:

def check_debug_mode if(defined?(DEBUG_MODE))
    puts "Yup" else puts "Nope" endend#first check - nothing definedcheck_debug_mode

DEBUG_MODE=true#second check - debug setcheck_debug_mode
#third check - DEBUG_MODE=nil# this will give a warning for redefining a constant, but other than that shouldn't effect the resultsDEBUG_MODE=nilcheck_debug_mode

Jeremy Wood

That's cool, I learned something too, #defined? actually responds to a defined value with a string describing the value passed which will evaluate as true but is not the bool value true.

asdf='asdf'

defined?(asdf) #=> "local-variable"

ASDF='asdf'

defined?(ASDF) #=> 'constant'

def asdf;end

defined?(asdf) #=> "method"

Cheers!

···

On 9/9/20 2:28 PM, Sean Felipe Wolfe wrote:

On Wed, Sep 9, 2020 at 12:10 PM Jeremy Wood <jwood@pearlcomm.com > <mailto:jwood@pearlcomm.com>> wrote:

    Sean,

    Please forgive me if I am misunderstanding something.

    In the event that TEST_MODE is undefined #defined? returns nil,
    which evaluates to false. In the case,

    that TEST_MODE is defined #defined returns true. So you should be
    able to delete the value just fine. The only adjustment I see is
    that your check code would need to look like:

    if(defined?(TEST_MODE) and TEST_MODE)

     #do test code

    else

     #do production code

    end

    Here is demo script:

    def check_debug_mode if(defined?(DEBUG_MODE))
         puts"Yup" else puts"Nope" end end #first check - nothing defined check_debug_mode

    DEBUG_MODE=true #second check - debug set check_debug_mode

    #third check - DEBUG_MODE=nil # this will give a warning for
    redefining a constant, but other than that shouldn't effect the
    results DEBUG_MODE=nil check_debug_mode

    Jeremy Wood

Ah, yes, what I didn't mention at the beginning. I am looking to do this for potentially multiple constants. Trying to simplify the problem to communicate it better to the group and ... oversimplified.

As I think the problem through though ... these test parameters are actually going to potentially be on or off depending on parameters we call the server with. So, having a single constant evaluated once upon startup doesn't work anyhow. I guess I'll have to use a variable.

Thanks everyone for your input, at least I learned a bit more about monkeypatching :slight_smile:

If you have multiple parameters that change at runtime, it might be simpler
to use a single global openstruct with the params as keys than multiple
variables.

martin

···

On Wed, Sep 9, 2020 at 12:29 PM Sean Felipe Wolfe <ether.joe@gmail.com> wrote:

On Wed, Sep 9, 2020 at 12:10 PM Jeremy Wood <jwood@pearlcomm.com> wrote:

Sean,

Please forgive me if I am misunderstanding something.

In the event that TEST_MODE is undefined #defined? returns nil, which
evaluates to false. In the case,

that TEST_MODE is defined #defined returns true. So you should be able to
delete the value just fine. The only adjustment I see is that your check
code would need to look like:

if(defined?(TEST_MODE) and TEST_MODE)

  #do test code

else

  #do production code

end

Here is demo script:

def check_debug_mode if(defined?(DEBUG_MODE))
    puts "Yup" else puts "Nope" endend#first check - nothing definedcheck_debug_mode

DEBUG_MODE=true#second check - debug setcheck_debug_mode
#third check - DEBUG_MODE=nil# this will give a warning for redefining a constant, but other than that shouldn't effect the resultsDEBUG_MODE=nilcheck_debug_mode

Jeremy Wood

Ah, yes, what I didn't mention at the beginning. I am looking to do this
for potentially multiple constants. Trying to simplify the problem to
communicate it better to the group and ... oversimplified.

As I think the problem through though ... these test parameters are
actually going to potentially be on or off depending on parameters we call
the server with. So, having a single constant evaluated once upon startup
doesn't work anyhow. I guess I'll have to use a variable.

Thanks everyone for your input, at least I learned a bit more about
monkeypatching :slight_smile:

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Sounds like another good suggestion also.

I did some more digging and found out about const_get as well ...
https://ruby-doc.org/core-2.5.1/Module.html#method-i-const_get

···

On Wed, Sep 9, 2020 at 1:37 PM Martin DeMello <martindemello@gmail.com> wrote:

If you have multiple parameters that change at runtime, it might be
simpler to use a single global openstruct with the params as keys than
multiple variables.

martin