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?
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?
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)
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:
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?
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
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)
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
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
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.
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.
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"?
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.