Duck typing problem

On Tuesday 03 June 2014 08:46:57, Roelof W. [email protected]
wrote:

def is_santa_clausable(obj)
obj.new()
end

but then I see this error message : NoMethodError: undefined method `new’
for #

Sure, .new is no instance method on an object. MyClass.new works and
returns a
new instance of the class “MyClass”.

What are you trying to do? Is this still related the original question?
AFAIR,
the original problem was solved.

  --- Eric

@@names.fetch(c.to_sym) {|k| raise ArgumentError, “Not a color name” }

This is awesome. But I tried

@@names.fetch(c.to_sym, raise(ArgumentError, “Not a color name”))

which didn’t work, because it is throwing an exception, for both cases
keyfound/not found. But didn’t try the block one. Don’t know why block
one worked, but not the other one which I
tried.

Matthew K. schreef op 3-6-2014 8:08:

On 3 June 2014 16:01, Roelof W. <[email protected]> wrote:
Matthew K. schreef op 3-6-2014 7:44:
On 3 June 2014 15:13, Roelof W. <[email protected]> wrote:
Matthew K. schreef op 3-6-2014 2:10:
??? A more Ruby way might be to have Color.lookup(color) be perfectly happy to accept a Color object. Then you'd have:

?? def scribble color
?? ?? color = Color.lookup color???
?? ?? ...
?? end

??? For comparison, see Kernel#Integer and friends.???

thanks,
But what if someone does this

def scribble color.new
???????? color = Color.lookup ???
???????? ....
end


That's
                        not valid Ruby code, I don't know what
                        you're trying to represent there. But this
                        is what I was thinking:</div>
                      <div
                        style="font-family:georgia,serif;color:rgb(7,55,99)"><br>
                      </div>
                      <div style="color:rgb(7,55,99)"><font size="1"
                          face="courier new, monospace">?? class
                          Color</font></div>
                      <div style="color:rgb(7,55,99)"> <font
                          size="1" face="courier new, monospace">?? 

??
@@names = {


?? ?? ??
black:
Color.new(0,0,0),

??
??
?? white:
Color.new(255,255,255),

?? ??
}

??
??
def Color.lookup c

?? ?? ??
case c

??
??
?? when Color

?? ?? ?? ??
c

??
??
?? when Symbol, String


?? ?? ?? ??
if
@@names[c.to_sym]

?? ?? ?? ??
??
@@names[c.to_sym]

?? ?? ?? ??
else

?? ?? ?? ??
??
raise ArgumentError, “Not a color
nane”

??
??
?? ?? end

?? ?? ??
else


??
??
?? ?? raise ArgumentError, “can’t convert
#{c.class.name} into
Color”

??
??
?? end

?? ??
end

??
end




??
def scribble color

?? ?? color
                          Color.lookup color</font></div>
                      <div style="color:rgb(7,55,99)"> <font
                          size="1" face="courier new, monospace">?? 

??


??
end





This
is the opposite of duck-typing, it’s
effectively doing type casting. If you call
Color.lookup with a Color object, you get it
back unmodified. If you call it with no
parameters, you get a generic Ruby
“ArgumentError: wrong number of arguments (0
for 1)” error.

???











Then Im confused by this test-case :



Test.assert_equals is_santa_clausable(SantaClaus.new),
true



Roelof








???Don’t
confuse the function definition and the thing that calls the
function. If you had my definition above, you could then
call:




?? ?? scribble
Color.new(…)

?? ?? scribble
:black

?? ?? scribble
‘white’

?? ?? scribble
Color.lookup(‘black’)





but
not:





?? ?? scribble
42???

?? ?? scribble
Array.new




etc.???












Oke, so I did this :



def is_santa_clausable(obj)

?? obj.new()

end

??

but then I see this error message : NoMethodError: undefined method
`new’ for #

Also changing obj to SantaClaus gives the same error.



Roelof


On Tuesday 03 June 2014 15:44:13, Matthew K. [email protected]
wrote:

That’s not valid Ruby code, I don’t know what you’re trying to represent
there. But this is what I was thinking:

[…]

That seems to be a pretty elegant solution.

I’d remove the “Color.lookup” code in #scribble, however. IMHO, it
introduces
alot of ambiguity: The user gets accustomed to methods that just take “a
sensible parameter”, and in the end, comes up with some kind of
parameter the
programmer hasn’t thought of during API design.

(Disclaimer: I write C++ most of the time, and, by no means, have any
authority whatsover in Ruby API design. ;-))

What about:

—%<—
class Color
def self.
return self.lookup sym
end
end
—>%—

That would allow easy access to the most commonly used color values and
allow
the user to just call:

—%<—
scribble Color[:black]
—>%—

Sorry for hijacking this thread. I know it becomes quite philosphical
this
way, but I’m very much interested in your opinions.

    --- Eric

On Tuesday 03 June 2014 15:10:06, Roelof W. [email protected]
wrote:

Yes, it is still related.
if that problem is solved I miss the answer somehow.

In a nutshell: For that particular testcase/exercise, you can use e.g.
.instance_methods to check for your required methods.

The rest of the thread evolved around the discussion whether checking
for an
interface in Ruby is actually good design.

HTH.

  --- Eric

Eric MSP Veith schreef op 3-6-2014 15:23:

  --- Eric

Oke,

Im going to read the .instance_methods and hope I see how it works when
I have test(roelof.new)

Roelof

Eric MSP Veith schreef op 3-6-2014 14:56:

What are you trying to do? Is this still related the original question? AFAIR,
the original problem was solved.

  --- Eric

Yes, it is still related.
if that problem is solved I miss the answer somehow.
Could someone tell me where it was.

Roelof

On Tuesday 03 June 2014 16:51:07, Roelof W. [email protected]
wrote:

Sorry,. I read the whole topic again but I cannot find anything about
.instance_methods or do you mean .lookup or ,responds_to.

Then I still not clear to me what I schould do when I see
SantaClaus(SantaClaus.new)
Could I do SantaClaus.lookup SantaClaus.new ?

AFAIR, what you want to archieve is to check whether an Object responds
to a
number of methods, i.e., “implements an interface”. (Please not the
quotation
marks, I’m still not happy with that notion.)

So, suppose your “interface” consists of the methods “method_a”,
“method_b”
and “method_c”, you check whether a given object responds to all three.

The first, simple version can then look like this:

def test_responds_to_my_methods
  my_obj = MyClass.new
  responds_to_all = true

  [ :method_a, :method_b ].each do |method|
    responds_to_all &= my_obj.respond_to? method
  end
end

The method .instance_methods returns an Array of Symbols, each Symbol
being
one method the object responds to.

You can also pass “false” as parameter to .instance_methods in order to
only
include the methods the class itself defines. This allows you even
better
“interface checking”.

Consider:

class MyPseudoInterface
  def method_a
  end

  def method_b
  end
end


MyPseudoInterface.instance_methods(false) # => [:method_a, :method_b]

If you’ve got an object, you need to gain access to the class before you
can
call .instance_methods. You do that using “my_obj.class”, i.e.,
“my_obj.class.instance_methods”.

(Notice the dot instead of the hash in the text: An instance method is
typically written using an hash as separator, e.g.,
MyClass#an_instance_method. Class methods are separated using a dot.)

Putting it all together, you can solve your exercise.

HTH.

  --- Eric

Eric MSP Veith schreef op 3-6-2014 17:14:

responds_to_all &= my_obj.respond_to? method

Oke,

I now have this :

def is_santa_clausable(obj)
responds_to_all = true
[:say_ho_ho_ho, :distribute_gifts, :go_down_the_chimney].each do
|method|
responds_to_all &= obj.respond_to? method
end
end

But Instead of true of false I see this [:say_ho_ho_ho,
:distribute_gifts, :go_down_the_chimney] as output.
Which I find wierd. because responds_to_all is true and obj.responds_to?
method schould also be true or false.

Roelof

Roelof W. schreef op 3-6-2014 16:28:

interface in Ruby is actually good design.
Roelof

Sorry,. I read the whole topic again but I cannot find anything about
.instance_methods or do you mean .lookup or ,responds_to.

Then I still not clear to me what I schould do when I see
SantaClaus(SantaClaus.new)
Could I do SantaClaus.lookup SantaClaus.new ?

Roelof

The result of #each is the thing that was iterated over.

Enumerable#all? might be good here:

[:say_ho_ho_ho, :distribute_gifts, :go_down_the_chimney].all? do

|method|
obj.respond_to?(method)
end

Wayne C. schreef op 3-6-2014 18:56:

The result of #each is the thing that was iterated over.

Enumerable#all? might be good here:

[:say_ho_ho_ho, :distribute_gifts, :go_down_the_chimney].all? do
|method|
obj.respond_to?(method)
end

Thanks

Finally solved this problem.

Roelof

Because a block isn’t executed until later, but a regular parameter has
to be evaluated before the method (in this case #fetch) is even called.

Consider:

my_object.some_method( foo, bar + 2)

You have to calculate bar + 2 before you can pass it to #some_method

Yes it is exactly like that. For some moment I forgot that. Thanks
Matthew.

On Jun 3, 2014 11:15 PM, “Eric MSP Veith” [email protected]
wrote:

I’d remove the “Color.lookup” code in #scribble, however. IMHO, it
introduces
alot of ambiguity: The user gets accustomed to methods that just take “a
sensible parameter”, and in the end, comes up with some kind of parameter
the
programmer hasn’t thought of during API design.

That’s what ArgumentError is for :wink:

It’s also tightly coupled to the idea of duck-typing: if any object can
do
the job, it’s good enough.

[…]

scribble Color[:black]
—>%—

What happens with: ´scribble Color[:banana]´ ?

The only big difference between yours and mine is where we write my case
statement. (Your caller has to choose what to pass to #scribble, based
on
whether it has a Symbol or a Color object.)

I put the case in Color because I figure that’s the expert on
recognising
and extracting colour information out of unlikely places.

If Color was a simpler class, one could argue that the casting should
happen in #scribble, because that’s the interface between user input and
a
canvas (for example), so it’s an expert in human-to-technical
translation.

By pushing it out further, it could be valid, but you’re making
the(/every)
caller become the expert. It does allow you to create a MyColor class,
which has a similar enough API to the original Color class (i.e. it
quacks
and waddles) that it could work in #scribble… But now the author of
MyColor needs to be an expert in Color and #scribble, and the caller
either needs even more expertise, or faith. And if it’s faith, you’re
back
where we started, by just throwing random objects at #scribble until one
sticks.

Sorry for hijacking this thread. I know it becomes quite philosphical this
way, but I’m very much interested in your opinions.

I think we’re not far from duck typing, especially as it relates to API
design choices.