Basic question about Fixnum & Integer


#1

Hello,
I’m really new to Ruby and rather new to OOP in general. I’ve been
using Perl for about 7 years now and have a fairly good understanding of
that language. I’ve never really entertained Python to any serious
degree beyond ‘Hello World’. Now you know my background.

I tried to do the following:

13.lcd 3

and it failed in the irb.

Why?

My thinking is that 13 is a Fixnum class and Fixnum inherits Integer.
Integer has a method ‘lcd’ that returns the least common denominator.
Since Fixnum < Integer then all the methods of Integer should be
available to all the child objects (Fixnum and super). And if this is
true, then calling a method like I did (Fixnum#lcd) implies an
inheritance search to find that class.

But my thinking seems to not reflect Ruby very well.

Can someone please tell me what I did wrong in the code and also in
thought? It’s little niggly bits like this that get frustrating.


#2

Tom A. wrote:

and it failed in the irb.
But my thinking seems to not reflect Ruby very well.

Can someone please tell me what I did wrong in the code and also in
thought? It’s little niggly bits like this that get frustrating.

Hi Tom,

There is no method named “lcd” on Integer, unless perhaps you’re using
an outside library which
gives you this functionality.

irb(main):016:0> 5.respond_to? :lcd
=> false

To check what methods an Integer does have you can use the
public_methods method on any number.

irb(main):017:0> 5.public_methods.sort
=> ["%", “&”, “*”, “**”, “+”, “+@”, “-”, “-@”, “/”, “<”, “<<”, “<=”,
“<=>”, “==”, “===”, “=~”, “>”,
“>=”, “>>”, “[]”, “^”, “id”, “send”, “abs”, “between?”, “ceil”,
“chr”, “class”, “clone”,
“coerce”, “display”, “div”, “divmod”, “downto”, “dup”, “eql?”, “equal?”,
“extend”, “floor”,
“freeze”, “frozen?”, “hash”, “id”, “id2name”, “inspect”,
“instance_eval”, “instance_of?”,
“instance_variable_get”, “instance_variable_set”, “instance_variables”,
“integer?”, “is_a?”,
“kind_of?”, “method”, “methods”, “modulo”, “next”, “nil?”, “nonzero?”,
“object_id”, “prec”,
“prec_f”, “prec_i”, “private_methods”, “protected_methods”,
“public_methods”, “quo”, “remainder”,
“respond_to?”, “round”, “send”, “singleton_method_added”,
“singleton_methods”, “size”, “step”,
“succ”, “taint”, “tainted?”, “times”, “to_a”, “to_f”, “to_i”, “to_int”,
“to_s”, “to_sym”,
“truncate”, “type”, “untaint”, “upto”, “zero?”, “|”, “~”]

You can also check ruby-doc for method documentation online,
http://www.ruby-doc.org/

Zach


#3

No, you don’t have to require integer, because it is in the core. The
core is always available. You can read the docs here:

http://www.ruby-doc.org/core/

And there is a standard library too:

http://www.ruby-doc.org/stdlib/

Most of these are not available by default. If you want to use a YAML
parser, you have to require YAML.


#4

Jules wrote:

parser, you have to require YAML.

Thanks for the references.

For some reason I can’t get my installation of Ruby to do what the
examples show:

6.lcm 7

return

6.lcm 7
NoMethodError: undefined method `lcm’ for 6:Fixnum
from (irb):17
from :0

6.lcm(7)
NoMethodError: undefined method `lcm’ for 6:Fixnum
from (irb):18
from :0

This is too simple to get wrong?


#5

zdennis wrote:

13.lcd 3
inheritance search to find that class.
an outside library which gives you this functionality.

irb(main):016:0> 5.respond_to? :lcd
=> false

Yeah… I just caught that.
lcm

shoud I require integer then?


#6

On Jan 16, 2006, at 3:50 PM, Tom A. wrote:

This is too simple to get wrong?

You must require ‘mathn’

example:

require ‘mathn’

6.lcm(7) # -> 42

  • Daniel

#7

On Jan 16, 2006, at 7:50 AM, Tom A. wrote:

This is too simple to get wrong?

I had never seen the #lcm method before, but I see it on ruby-doc,
and I see it in my local ri, and it also doesn’t really exist for me.
Very odd. Looks like for some reason the documentation is wrong.

Slim:~ gavinkistner$ irb --version
irb 0.9.5(05/04/13)
Slim:~ gavinkistner$ irb
irb(main):001:0> VERSION
=> “1.8.4”
irb(main):002:0> 6.respond_to? :lcm
=> false
irb(main):003:0> 6.methods.sort
=> ["%", “&”, “*”, “**”, “+”, “+@”, “-”, “-@”, “/”, “<”, “<<”, “<=”,
“<=>”, “==”, “===”, “=~”, “>”, “>=”, “>>”, “[]”, “^”, “id”,
send”, “abs”, “between?”, “ceil”, “chr”, “class”, “clone”,
“coerce”, “display”, “div”, “divmod”, “downto”, “dup”, “eql?”,
“equal?”, “extend”, “floor”, “freeze”, “frozen?”, “hash”, “id”,
“id2name”, “inspect”, “instance_eval”, “instance_of?”,
“instance_variable_get”, “instance_variable_set”,
“instance_variables”, “integer?”, “is_a?”, “kind_of?”, “method”,
“methods”, “modulo”, “next”, “nil?”, “nonzero?”, “object_id”, “prec”,
“prec_f”, “prec_i”, “private_methods”, “protected_methods”,
“public_methods”, “quo”, “remainder”, “respond_to?”, “round”, “send”,
“singleton_method_added”, “singleton_methods”, “size”, “step”,
“succ”, “taint”, “tainted?”, “times”, “to_a”, “to_f”, “to_i”,
“to_int”, “to_s”, “to_sym”, “truncate”, “type”, “untaint”, “upto”,
“zero?”, “|”, “~”]
irb(main):004:0> quit
Slim:~ gavinkistner$ ri lcm
------------------------------------------------------------ Integer#lcm
lcm(other)

  Returns the lowest common multiple (LCM) of the two arguments
  (self and other).

  Examples:

    6.lcm 7        # -> 42
    6.lcm 9        # -> 18

#8

On Jan 16, 2006, at 4:01 PM, Daniel H. wrote:

You must require ‘mathn’

Actually, this is partially wrong. #lcm is defined in rational, but
mathn requires rational. So require ‘rational’, but require ‘mathn’
works too. Sorry.

  • Daniel

#9

Daniel H. wrote:

require ‘mathn’

6.lcm(7) # -> 42

  • Daniel

Thank you. This is the first I’ve heard of mathn, even from the Integer
doc pages. I missed it.

Backing up…

I was assuming that to include a module I would call the class name on
the assumption that the class name matches the class file (similar to
perl and java). But this isn’t the case with mathn.

Doing some more poking about:
ri has nothing known about mathn or anything like it.
ri tells me that Integer.lcm is a real method.
but to invoke this method on a Fixnum, I have to require a package name
that isn’t mentioned in the lcm, Fixnu, or Integer docs.

Granted, I found all this from the web pages for the standard library,
but it wasn’t intuitive. It doesn’t even mention that mathn is
responsible for this lcm method.

This is really frustrating. Is the documentation wrong or did I just
miss something that every Ruby-ite should know?


#10

On Jan 16, 2006, at 8:05 AM, Daniel H. wrote:

On Jan 16, 2006, at 4:01 PM, Daniel H. wrote:

You must require ‘mathn’

Actually, this is partially wrong. #lcm is defined in rational, but
mathn requires rational. So require ‘rational’, but require ‘mathn’
works too. Sorry.

Ah, so the documentation isn’t wrong, it’s just confusing.

Tom, the issue is that Ruby allows different libraries to modify and
extend the same class. (So, Integer has a base set of methods
included in the core, but including libraries like Rational adds
additional methods.) Ruby’s documentation system (RDoc) has the
ability to conveniently merge the methods from all those libraries
under the single class to which they belong. Unfortunately, it
doesn’t make clear which file or library each method comes from, and
the people who wrote the documentation for these ‘addon’ methods did
not make clear which library they came from.

Your confusion is certainly understandable.


#11

Gavin K. wrote:

    from (irb):18
    from :0

This is too simple to get wrong?

I had never seen the #lcm method before, but I see it on ruby-doc, and
I see it in my local ri, and it also doesn’t really exist for me. Very
odd. Looks like for some reason the documentation is wrong.

Oh thank God!!! I thought I was going clearly insane.
If I am, at least I won’t be alone…


#12

Gavin K. wrote:

the documentation for these ‘addon’ methods did not make clear which
library they came from.

Your confusion is certainly understandable.

OK, I understand how the documentation got there. It’s a merged super
set of all the methods from all the libraries. Makes sense.

But it would be really useful if there was something in the docs to
delineate where methods come from if they aren’t provided in the core.

Otherwise you end up with people like me who have a lot less hair on
either side of their head.

How would I go about identifying something like this in the future?
Where I find an ri documented method that isn’t in the core.
http://www.ruby-doc.org/stdlib/
by itself doesn’t provide enough information unless I just poke around
the table of contents hoping to get lucky.


#13

On Mon, 16 Jan 2006 16:12:15 +0100, Tom A. removed_email_address@domain.invalid
wrote:

ri has nothing known about mathn or anything like it.

Err. Mind the terms, including a module in Ruby is something VERY
different from requiring a library.

Heavy spoonfeeding follows.

That said, a large majority of libraries are named according to the
modules / classes defined in them. E.g.: A class named
Toys::Fluffy::Teddy
will be very probably defined in a file called “toys/fluffy/teddy.rb”
relative to somewhere on your Ruby library path.

However, that is only a convention, and is not enforced. Some libraries,
like “mathn”, don’t define any new modules or classes, but instead
(ab)use
the metaprogramming and reflective capacities of Ruby and modify
existing
modules / classes by defining new methods or changing the behaviour of
existing ones.

ri only looks up information on modules, classes, and methods in
whatever
libraries were merged in your documentation, it doesn’t know anything
about libraries. The HTML backend to rdoc stores generally more
information, like library synopses, source file names, and required
files.
Personally, I prefer only the Ruby core doeumentation available for ri,
where problems with what required what when aren’t an issue, and look up
libraries on the web.

Anyways, if you’re still confused about something - or more confused
than
before - feel free to bug.

David V.


#14

David V. wrote:

Err. Mind the terms, including a module in Ruby is something VERY
different from requiring a library.

My mix in terminology is a reflection of my origins. Perl uses Modules.

Heavy spoonfeeding follows.

That said, a large majority of libraries are named according to the
modules / classes defined in them. E.g.: A class named
Toys::Fluffy::Teddy will be very probably defined in a file called
“toys/fluffy/teddy.rb” relative to somewhere on your Ruby library path.

I like this idea. Obviously because it’s so very perl-ish.
But it also makes sense.

However, that is only a convention, and is not enforced. Some
libraries, like “mathn”, don’t define any new modules or classes, but
instead (ab)use the metaprogramming and reflective capacities of Ruby
and modify existing modules / classes by defining new methods or
changing the behaviour of existing ones.

This should be discouraged or at least a consistent alternative. In any
event, if it were possible to identify methods that require more than
the stdlib or core…

Anyways, if you’re still confused about something - or more confused
than before - feel free to bug.

Not so much anymore, just more cautious.
I like what I’ve seen so far but my lack of familiarity makes everything
seem so shockingly bizarre at times. I have to check myself to make
sure.

Thanks. This has been a lesson.


#15

On Mon, 16 Jan 2006 22:27:37 +0100, Tom A. removed_email_address@domain.invalid
wrote:

This should be discouraged or at least a consistent alternative. In any
event, if it were possible to identify methods that require more than
the stdlib or core…

Good luck finding support for that. Of course, noone dabbles into this
sort of voodoo without his metaprogramming helmet. Banging your head
against the wall in frustration at stuff not working can result in
severe
head trauma. Ruby allows you to do this sort of magic, and do it
definately more easily and cleanly than in other languages directly
manipulating superclass lists and property dictionaries and all such
foolishness. This is a very distinctive feature of Ruby, and no chance
in
hell it’s getting nerfed or discouraged. It’s runninf with scissors, but
sometimes you need to cut something really quickly :wink:

That said, libraries that alter what is already present in other
namespaces are VERY rare. Not actively discouraged in the least, but
rare.

And if you use HTML documentation, you can distinguish what was defined
where, as was previously mentioned.

Anyways, if you’re still confused about something - or more confused
than before - feel free to bug.

Not so much anymore, just more cautious.
I like what I’ve seen so far but my lack of familiarity makes everything
seem so shockingly bizarre at times. I have to check myself to make
sure.

Takes getting used to, 's all.

David V.


#16

On 1/16/06, Tom A. removed_email_address@domain.invalid wrote:

But it would be really useful if there was something in the docs to
delineate where methods come from if they aren’t provided in the core.

Two tricks helped me to determine where the method is defined:

  1. Every rdoc page mentions at the top which files the methods are
    defined in. For example, the Integer core rdoc page[1] has the
    following near the top:

    Class Integer
    In: numeric.c
    lib/rational.rb
    Parent: Numeric

From the file it’s often possible to guess the library. In this case,
the header doesn’t tell us enough to be sure whether lcm is coming
from; from numeric.c (ie. inheritance from Numeric) or
lib/rational.rb.

  1. Going to the documentation for the actual method[2], you can click
    on the method name and it will show you the source for the method[3],
    preceded by a comment telling you the file name and line number[4].
    Having narrowed it down to one file, we can again try to guess the
    library name.

I’ll agree with you that it should be easier to determine the library
that defined the method. But in the meantime, these tricks can help.

Jacob F.

[1] http://www.ruby-doc.org/core/classes/Integer.html
[2] http://www.ruby-doc.org/core/classes/Integer.html#M000283
[3] http://www.ruby-doc.org/core/classes/Integer.src/M000283.html

[4] At least for the methods I checked. lcm has it. A few other of the
pure ruby methods had it. Some C methods I checked didn’t, but seeing
that they were C was enough to give them away. YMMV.


#17

Hi –

On Tue, 17 Jan 2006, David V. wrote:

existing ones.
and do it definately more easily and cleanly than in other languages
directly manipulating superclass lists and property dictionaries and
all such foolishness. This is a very distinctive feature of Ruby,
and no chance in hell it’s getting nerfed or discouraged. It’s
runninf with scissors, but sometimes you need to cut something
really quickly :wink:

mathn is in the standard library, so it’s got a different relation to
the rest of the distribution than a third-party library would.

That said, libraries that alter what is already present in other
namespaces are VERY rare. Not actively discouraged in the least, but
rare.

It depends what you mean by actively. Dozens of people have certainly
counseled against it, over the years. The difficulty, for me, has
always been how to harness this particular kind of flexibility and
openness, a prospect I’ve always found more intriguing than the
prospect of just deciding that it exists for the purpose of being
avoided. I think that if Ruby 2.0 has selector namespaces, we’ll
probably see some very creative and productive runtime class changing.

Or maybe not. I’ve heard extremely little about anyone actually using
any of the libraries that make block-scoped core changes possible.
Maybe there isn’t all that great a demand for orderly ways to do it.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#18

On Tue, 17 Jan 2006 04:05:00 +0100, removed_email_address@domain.invalid wrote:

It depends what you mean by actively. Dozens of people have certainly
counseled against it, over the years. The difficulty, for me, has
always been how to harness this particular kind of flexibility and
openness, a prospect I’ve always found more intriguing than the
prospect of just deciding that it exists for the purpose of being
avoided. I think that if Ruby 2.0 has selector namespaces, we’ll
probably see some very creative and productive runtime class changing.

Nevertheless, it’s nice to have it there. Heck, Rails runs on so much
deep
magic it ain’t pretty, if it’s not actually changing core libraries. And
selector namespaces sound like a nice way to prevent gods know what
including gods know what gods know where, causing the mother of all
obscure bugs sooner or later.

Or maybe not. I’ve heard extremely little about anyone actually using
any of the libraries that make block-scoped core changes possible.
Maybe there isn’t all that great a demand for orderly ways to do it.

Well d’oh. They’re rare, and they usually give unconventional behaviour
to
existing code, I’d be very surprised if they were present in stable
prouction-code due to the risks involved. But if I wanted to make lessay
a
symbolic calculator, the tweaks made by “mathn” would come in handy. And
having Kernel#y present for YAML pretty-printed inspect is also very
convenient, and I’d rather have it than read the slightly ugly ducks
default inspects, or have to type explicit namespace references for
something that trivial and frequently used.

David V.


#19

David V. wrote:

of Ruby and modify existing modules / classes by defining new
against the wall in frustration at stuff not working can result in
severe head trauma. Ruby allows you to do this sort of magic, and do
it definately more easily and cleanly than in other languages directly
manipulating superclass lists and property dictionaries and all such
foolishness. This is a very distinctive feature of Ruby, and no chance
in hell it’s getting nerfed or discouraged. It’s runninf with scissors,
but sometimes you need to cut something really quickly :wink:

Can’t disagree with the need.
But if the person doing the running doesn’t know they are carrying
scissors…

The other issue I’m running into is that out of three people and four
machines, I only have one that lists mathn functions in ‘ri’ even though
it’s supposed to be in the standard library (v1.8). So you can imagine
the confusion we are all having with me pulling methods out of thin air
that no one else can even see.

I haven’t been able to put together enough of a picture on the docs part
of the issue to know where the problem lies, me, the distros (several)
or RDocs. It’s just an observation.

I’m not giving up. I feel I’ve just fallen with the scissors and
skinned my knee.


#20

On Tue, 17 Jan 2006 14:37:50 +0100, removed_email_address@domain.invalid wrote:

I think we’re talking about two different things. I’m referring to
Ruby Behaviors, Import Module, and a third project whose name I can’t
remember but which does something similar: allow for temporary changes
to core classes.

David

Heh, apparently, I had the standard modification of existing classes in
mind, without extra scoping libraries all the time. Happens. I blame the
caffeine.

David V.