Avoiding nil.methodcalls short and cheap

Hi,

I often have to check if a methodcall A is not returning nil before
calling another method on the return value of the methodcall A. I'm
looking for a short and cheap (avoiding to call method A two times like
in this example where xmltag.get_text is method A:
textvalue = xmltag.get_text.value if xmltag.get_text
)
The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

Thanks,
.tr!

···

--
Posted via http://www.ruby-forum.com/.

textvalue = (text = xmltag.get_text) && text.value

Farrel

···

On 22/06/07, Thorsten Rossner <rossnet@gmx.de> wrote:

textvalue = xmltag.get_text.value if xmltag.get_text

Consider this:

begin
  textvalue = xmltag.get_text.value
rescue NoMethodError
end

···

On Jun 22, 4:53 pm, Thorsten Rossner <ross...@gmx.de> wrote:

Hi,

I often have to check if a methodcall A is not returning nil before
calling another method on the return value of the methodcall A. I'm
looking for a short and cheap (avoiding to call method A two times like
in this example where xmltag.get_text is method A:
textvalue = xmltag.get_text.value if xmltag.get_text
)
The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

Thanks,
tr!

--
Posted viahttp://www.ruby-forum.com/.

Hi,

I often have to check if a methodcall A is not returning nil before
calling another method on the return value of the methodcall A. I'm
looking for a short and cheap (avoiding to call method A two times like
in this example where xmltag.get_text is method A:
textvalue = xmltag.get_text.value if xmltag.get_text

Variations using just logic operators and conditionals - I think the
last two are probably best (though it vary by context)

# Short, unclear
textvalue = xmltag.get_text
textvalue &&= textvalue.value

# With if
textvalue = textvalue.value if textvalue = xmltag.get_text

# Longer, clearer
if textvalue = xmltag.get_text
  textvalue = textvalue.value
end

# Re-using the variable, one-line
textvalue = xmltag.get_text and textvalue = textvalue.value

# With new variable, possibly the cleanest
textvalue = (text = xmltag.get_text and text.value)

# You can also redefine the object in question
def xmltag.get_text_value
   text = get_text && text.value
end
textvalue = xmltag.get_text_value

···

On 6/22/07, Thorsten Rossner <rossnet@gmx.de> wrote:

)
The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

Thanks,
.tr!

--
Posted via http://www.ruby-forum.com/\.

--
Hazzle free packages for Ruby?
RPA is available from http://www.rubyarchive.org/

The conceptually simplest is:

  get_text = xmltag.get_text
  textvalue = get_text.value if get_text

But as you will note, it takes up two lines. Of course you can always
fix that:

  get_text = xmltag.get_text; textvalue = get_text.value if get_text

Even so, I often write this as:

  if get_text = xmltag.get_text
    textvalue = get_text.value
  end

Simply b/c I often find long one liners unpleasant to read.

However, I just want to point out that if there is no get_text, than
textvalue is not being assigned at all. Unless you have previously set
textvalue to a default, that could lead to an undefined local variable
error. So you might consider:

  textvalue = (get_text = xmltag.get_text) ? get_text.value : nil

T.

···

On Jun 22, 5:53 am, Thorsten Rossner <ross...@gmx.de> wrote:

Hi,

I often have to check if a methodcall A is not returning nil before
calling another method on the return value of the methodcall A. I'm
looking for a short and cheap (avoiding to call method A two times like
in this example where xmltag.get_text is method A:
textvalue = xmltag.get_text.value if xmltag.get_text
)
The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

Thorsten Rossner <rossnet@gmx.de> writes:

The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

Since no one has pointed this out, I'll remind you that this *is*
Ruby, which has the relatively uncommon feature of allowing one to add
to core classes, so we can use that if there's only one or two methods
you'd like to call frequently. First note:

irb(main):001:0> nil.freeze
=> nil

Then, doing this somewhere:

class NilClass
  alias value freeze
end

Lets us do this in the main code:

textvalue = xmltag.get_text.value

And nils automatically get propagated.

···

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.to_a.last )
       puts "s=%q(#{s})",s.to_a.last

Thorsten Rossner wrote:

Hi,

I often have to check if a methodcall A is not returning nil before
calling another method on the return value of the methodcall A. I'm
looking for a short and cheap (avoiding to call method A two times like
in this example where xmltag.get_text is method A:
textvalue = xmltag.get_text.value if xmltag.get_text
)
The ideal solution would be a oneliner with only little complexity
calling method A just one time. Am I using the wrong approach here
anyway?

This the solution I use in *my* code for this common problem:
   textvalue = xmltag.get_text.ergo.value

This is my personal solution and I've never seen anyone use something like this, so it may not be a "common and accepted idiom" but it works well for me. YMMV

code for "ergo":

class NilClass
   def ergo
     @blackhole ||= Object.new.instance_eval do
       class << self
         for m in public_instance_methods
           undef_method(m.to_sym) unless m =~ /^__.*__$/
         end
       end
       def method_missing(*args); nil; end
       self
     end
     @blackhole unless block_given?
   end
end

class Object
   def ergo
     if block_given?
       yield(self)
     else
       self
     end
   end
end

I would avoid code that relies on logical operators to preserve values.
That is any code that uses logical operators and would break if you
put !!() around the expression is quite dodgy in my book.

Thanks

Michal

···

On 22/06/07, Eivind Eklund <eeklund@gmail.com> wrote:

On 6/22/07, Thorsten Rossner <rossnet@gmx.de> wrote:
> Hi,
>
> I often have to check if a methodcall A is not returning nil before
> calling another method on the return value of the methodcall A. I'm
> looking for a short and cheap (avoiding to call method A two times like
> in this example where xmltag.get_text is method A:
> textvalue = xmltag.get_text.value if xmltag.get_text

Variations using just logic operators and conditionals - I think the
last two are probably best (though it vary by context)

# Short, unclear
textvalue = xmltag.get_text
textvalue &&= textvalue.value

# With if
textvalue = textvalue.value if textvalue = xmltag.get_text

# Longer, clearer
if textvalue = xmltag.get_text
  textvalue = textvalue.value
end

# Re-using the variable, one-line
textvalue = xmltag.get_text and textvalue = textvalue.value

# With new variable, possibly the cleanest
textvalue = (text = xmltag.get_text and text.value)

# You can also redefine the object in question
def xmltag.get_text_value
   text = get_text && text.value
end
textvalue = xmltag.get_text_value

Thanks for quick and helpful answers! I hope all of you will have a
great weekend!

···

--
Posted via http://www.ruby-forum.com/.

Interesting... I like this. Nice use of fluent / magic dot notation.
This is a good use case for Functor too (see Facets):

  class NilClass
    def ergo
      @blackhole ||= Functor.new{ nil }
      @blackhole unless block_given?
    end
  end

One question, I'm not sure what you expect to be returned if a block
is given.

Besides that one issue, I'd like to add this to Facets and credit you.

T.

···

On Jun 23, 9:17 am, Daniel DeLorme <dan...@dan42.com> wrote:

Thorsten Rossner wrote:
> Hi,

> I often have to check if a methodcall A is not returning nil before
> calling another method on the return value of the methodcall A. I'm
> looking for a short and cheap (avoiding to call method A two times like
> in this example where xmltag.get_text is method A:
> textvalue = xmltag.get_text.value if xmltag.get_text
> )
> The ideal solution would be a oneliner with only little complexity
> calling method A just one time. Am I using the wrong approach here
> anyway?

This the solution I use in *my* code for this common problem:
   textvalue = xmltag.get_text.ergo.value

This is my personal solution and I've never seen anyone use something
like this, so it may not be a "common and accepted idiom" but it works
well for me. YMMV

code for "ergo":

class NilClass
   def ergo
     @blackhole ||= Object.new.instance_eval do
       class << self
         for m in public_instance_methods
           undef_method(m.to_sym) unless m =~ /^__.*__$/
         end
       end
       def method_missing(*args); nil; end
       self
     end
     @blackhole unless block_given?
   end
end

class Object
   def ergo
     if block_given?
       yield(self)
     else
       self
     end
   end
end

(... deleted ...)

I love the solution, and have one question: Is there any deeper
rationale behind the name "ergo"?

Eivind.

···

On 6/23/07, Daniel DeLorme <dan-ml@dan42.com> wrote:

Thorsten Rossner wrote:
> textvalue = xmltag.get_text.value if xmltag.get_text

This the solution I use in *my* code for this common problem:
   textvalue = xmltag.get_text.ergo.value

This is my personal solution and I've never seen anyone use something
like this, so it may not be a "common and accepted idiom" but it works
well for me. YMMV

code for "ergo":

And I would strongly disagree with this.

Returning the value of the true expression is defined behavior, and it
allows for considerable simplification of code. Having simpler code
means that you have less chance of errors and spend less time when
reading the code.

To my mind, dodgy code is code that is difficult to understand or
increase chance of errors, ie, the opposite of code that does
appropriate use of the preservation of values in logical operators.

Not that I'm particularly happy with any of the cases above - the
closest to "good" I found was textvalue = (text = tag.get_text and
text.get_value)

Eivind.

···

On 6/22/07, Michal Suchanek <hramrach@centrum.cz> wrote:

I would avoid code that relies on logical operators to preserve values.
That is any code that uses logical operators and would break if you
put !!() around the expression is quite dodgy in my book.

Trans wrote:

Interesting... I like this. Nice use of fluent / magic dot notation.
This is a good use case for Functor too (see Facets):

  class NilClass
    def ergo
      @blackhole ||= Functor.new{ nil }
      @blackhole unless block_given?
    end
  end

Indeed, that really simplifies the code.

One question, I'm not sure what you expect to be returned if a block
is given.

foo.ergo{ |o| o.bar } #=> result of bar
nil.ergo{ |o| o.bar } #=> nil
because sometimes some cases don't lend themselves very well to "magic dot" notation.

Besides that one issue, I'd like to add this to Facets and credit you.

By all means, I'd be honored.

Daniel

Eivind Eklund wrote:

I love the solution, and have one question: Is there any deeper
rationale behind the name "ergo"?

it's latin for "therefore", as in:

cogito = [2,2]
cogito.ergo.sum #=> 4

:wink:

Not always. It is defined behavior but unless you work exclusively in
Ruby you will have to deal with cases when true values are not
preserved. This makes the code more obscure, harder to read, and more
error prone.

The concept of logical operations is to preserve the logical value,
and you have to think twice about other properties they might or might
not have.

Thanks

Michal

···

On 22/06/07, Eivind Eklund <eeklund@gmail.com> wrote:

On 6/22/07, Michal Suchanek <hramrach@centrum.cz> wrote:
> I would avoid code that relies on logical operators to preserve values.
> That is any code that uses logical operators and would break if you
> put !!() around the expression is quite dodgy in my book.

And I would strongly disagree with this.

Returning the value of the true expression is defined behavior, and it
allows for considerable simplification of code. Having simpler code
means that you have less chance of errors and spend less time when
reading the code.

I know that (ergo is commonly used in my native tongue), I just didn't
feel that it really formed a rationale. On the other hand, I don't
have a better name handy...

Eivind.

···

On 6/26/07, Daniel DeLorme <dan-ml@dan42.com> wrote:

Eivind Eklund wrote:
> I love the solution, and have one question: Is there any deeper
> rationale behind the name "ergo"?

it's latin for "therefore", as in:

Eivind Eklund wrote:

···

On 6/26/07, Daniel DeLorme <dan-ml@dan42.com> wrote:

Eivind Eklund wrote:
> I love the solution, and have one question: Is there any deeper
> rationale behind the name "ergo"?

it's latin for "therefore", as in:

I know that (ergo is commonly used in my native tongue), I just didn't
feel that it really formed a rationale. On the other hand, I don't
have a better name handy...

Sorry, it seems I misunderstood the question. But I don't know what more 'rationale' is needed. To me, "a ergo b" reads like "b proceeds from a", which expresses the same logic as "a && a.b" IMHO no deeper rationale is required.

Daniel