Everything is a object?

James G. wrote:

On Apr 4, 2007, at 7:43 AM, Jamal S. wrote:

using it, but this has been misunderstood, you should somehow
and so attempts to reference it will fail to produce a reference to
an object. An attempt will also be made to apply the token to the
current object as a method, and if this too fails then the
interpreter has no choice but to flag an error condition because
semantically your program is broken - it makes no sense.

:smiley:

So until I assign something to it, the interpreter would know nothing
about what object it is.

I think it’s probably better to say that until you assign it, it
doesn’t exist. But yes, you are on the right track here.

In C# you can declare every variable what type it is like this:
String mystring;

I assume I could do that in Ruby also:
@var = String.new

But no need since Ruby would take care of this automatic when you
assign
something to variables.

C# cares what type a variable is. It uses that information for
things like method lookup. Ruby does not. A variable can hold
whatever you like:

str = String.new

str = 5 # Ruby doesn’t care that it’s not a String now

This is called “dynamic typing” and is one of the great features of
Ruby. It does take some getting use to though, if you are joining us
from a statically typed language.

When I write attributes in my code:
attr_assoccer :var

I assume > then < the interpreter knows only that @var is a object
(base
class)?

So before I can use @var.

Actually, the it doesn’t exist until you define it rule only applies
to local variables:

$ ruby -e ‘p local_var’
-e:1: undefined local variable or method `local_var’ for main:Object
(NameError)
$ ruby -e ‘p @inst_var
nil
$ ruby -e ‘p $global_var’
nil

However, the last two issue warnings when enabled (which I recommend):

$ ruby -we ‘p @inst_var
-e:1: warning: instance variable @inst_var not initialized
nil
$ ruby -we ‘p $global_var’
-e:1: warning: global variable `$global_var’ not initialized
nil

Hope that helps.

James Edward G. II

Actually I was trying to do it this way, when I started.

if @var.nil?
p “empty”
end

which works normal…but @var is nothing yet, and not declared, but still
its object of object class?

Ruby understand that everything start with @ is a object, either
reference or a type.

like in other language

@var = &reference
@var = object

when I type it

if var.nil?

var is unknown?

it’s not variable, neither object? what is it? nobody knows, throw
exception to the bad coder :stuck_out_tongue:

On Apr 4, 2007, at 8:30 AM, removed_email_address@domain.invalid wrote:

is exactly equivalent to:
end
Not “exactly equivalent.” It also silences the warning:

$ ruby -we ‘class Test; def var; @var; end; end; p Test.new.var’
-e:1: warning: instance variable @var not initialized
nil
$ ruby -we ‘class Test; attr_reader :var; end; p Test.new.var’
nil

James Edward G. II

On Apr 4, 3:01 pm, James Edward G. II removed_email_address@domain.invalid
wrote:

Ruby’s a pretty clever girl. :wink:

True, but maybe not advisable for beginners. We don’t want to go into
the whole shadowing and “class vs. self.class” business, when Jamal is
already having difficulties with the basics.

Christophe.

On Wed, Apr 04, 2007 at 10:19:47PM +0900, Jamal S. wrote:

Indeed, if a has not been given a value yet, it cannot be “nil” (“nil”
is a value, and an object), so this will fail.

That made me confused a little bit, How can nil be a class? and then a
method in object base class (nil?)

nil is an instance (the only instance) of class NilClass.

irb(main):001:0> nil.class
=> NilClass
irb(main):002:0> nil.class.ancestors
=> [NilClass, Object, Kernel]

On Wed, Apr 04, 2007 at 09:43:14PM +0900, Jamal S. wrote:

So until I assign something to it, the interpreter would know nothing
about what object it is.

No, it’s stronger than that.

If you don’t assign something to a local variable, then the interpreter
assumes you’re not talking about a local variable at all, but a method
call.

foo # 1. interpreted as ‘self.foo’ or equivalently
‘foo()’
foo.bar # 2. interpreted as ‘self.foo.bar’ or ‘foo().bar()’

foo = “x”

foo # 3. now foo is a local variable. This is an
expression
# whose value is the objected refered to by foo.
# i.e. the string “x”
foo.bar # 4. invokes ‘bar’ method on the object refered to
by ‘foo’

That’s because both method names and local variable names fall into the
same
namespace (alphanumeric names starting with lower case). There’s no “$”
to
distinguish a variable from a method as there is in Perl or PHP.

Is it a bit clearer now why it’s necessary to assign to a variable
before
it’s treated as a variable?

When I write attributes in my code:
attr_assoccer :var

I assume > then < the interpreter knows only that @var is a object (base
class)?

That’s something else. You’ve defined two methods in your class, ‘var’
and
‘var=’, which read and assign to instance variable @var respectively.

local variables are just scratch space on the stack. They are not
instance
variables on an object.

Brian.

On Apr 4, 3:19 pm, Jamal S. removed_email_address@domain.invalid wrote:

unknown wrote:

Yes. And I don’t see how it’s so surprising given plenty of languages
(including PHP) usually have many more keywords than Ruby has (some
have less, but they are less common).

They have plenty, but they don’t have something like defined?, they have
functions that act as defined? keyword.

So then just tread “defined?” as a function. It’s just not a method.

Think about it a moment. Let’s say I ask you: "Please send Steve
Somename a bunch of flow…

Great example :smiley: I love it :smiley:

Thanks :slight_smile: .

This whole “everything is an object” and “variables needn’t to be
declared” is something di…

Well someone should know her before me, to tell me about her, so
basically someone knows about her?

Yes, but not you, and if you follow the analogy from the examples, in
this case you were Ruby :slight_smile: .

Indeed, if a has not been given a value yet, it cannot be “nil” (“nil”
is a value, and an object), so this will fail.

That made me confused a little bit, How can nil be a class?

It’s not a class, it’s an object. And like any object, it has a class,
called NilClass.

and then a

method in object base class (nil?)

“nil?” is a separate method (the question mark is part of the name, so
“nil” and “nil?” refer to different things), which is defined in
Object (what you call the object base class) to return false, and
overridden in NilClass, to return true. Just try it in irb:

a = Object.new
a.nil?
=> false
nil.nil?
=> true

You are actually completely free to define your own class with a nil?
method returning true, although I wouldn’t know why you’d want to do
that.

class SomeNilClass
def nil?
true
end
end

a = SomeNilClass.new
a.nil?
=> true

Christophe.

On Apr 4, 3:37 pm, James Edward G. II removed_email_address@domain.invalid
wrote:

Not “exactly equivalent.” It also silences the warning:

$ ruby -we ‘class Test; def var; @var; end; end; p Test.new.var’
-e:1: warning: instance variable @var not initialized
nil
$ ruby -we ‘class Test; attr_reader :var; end; p Test.new.var’
nil

I didn’t know about that one. Thanks.

Also, thanks for pointing out the global variables, I had forgotten
about them :slight_smile: .

Christophe.

On Apr 4, 7:19 am, Jamal S. removed_email_address@domain.invalid wrote:

if a.nil?
p ‘thanks’;
end

Indeed, if a has not been given a value yet, it cannot be “nil” (“nil”
is a value, and an object), so this will fail.

That made me confused a little bit, How can nil be a class? and then a
method in object base class (nil?)

Slim:~ gkistner$ irb

irb(main):001:0> a = nil
=> nil

irb(main):002:0> a.class
=> NilClass

irb(main):003:0> nil.class
=> NilClass

irb(main):008:0> NilClass.instance_methods(false)
=> [“to_s”, “|”, “to_f”, “to_a”, “&”, “^”, “nil?”, “to_i”,
“inspect”]

Just like “true” is the literal way to express an instance of the
TrueClass and “[]” is the literal way to express an instance of the
Array class, “nil” is the literal way to express an instance of the
NilClass. That class has methods, like any other. One of those methods
is named “nil?”. (Not that it makes much difference, but note that
“nil?” is a different name from “nil”; the question mark is part of
the name.)

I say that it doesn’t make much difference because you can have method
names that are the same as a built-in literal. For example:

irb(main):001:0> class Foo
irb(main):002:1> def true
irb(main):003:2> “maybe”
irb(main):004:2> end
irb(main):005:1> end
=> nil

irb(main):006:0> f = Foo.new
=> #Foo:0x3847bc

irb(main):007:0> puts f.true
maybe
=> nil

Heck, lots of built-in classes have a method named “[]”, usually used
for accessing methods. Indeed, the Array class, which can be
instantiated by the literal [], is the primary example of it. So if
you write:

irb(main):008:0> [][]
ArgumentError: wrong number of arguments (0 for 1)
from (irb):8:in `[]’
from (irb):8

…what’s going on is the first [] instantiate a new array instance,
and the second [] call the “[]” method on them…which requires a
single argument, hence the error.

irb(main):009:0> [ ‘a’, ‘b’, ‘c’, ‘d’ ][ 2 ]
=> “c”

It has been long topic now, and very helpful, I must admit I really love
the Ruby Community, such Community is hard to find other places :slight_smile:

I want to thanks everyone very much :slight_smile:


I think now I understand completely why the following code below is
throwing exception:

puts myvar

register.rb:1: undefined local variable or method ‘myvar’ for

main:Object

Ruby don’t know what “myvar” is, it could not find any local variable
with that name, or any method in the main:Object (base class)


The code below would not throw any exception:
puts @myvar

nil

Ruby already know whatever start with @ would be instance of something,
if not then it would still be nil object, means false.

puts @myvar.class.to_s

NilClass

puts @myvar=“string”.class.to_s

String


The Accessors only provide you with the set and get properties similar
to other languages, when you declare something like this:

attr_accessor :myvar

You would have an instance of nil object.

class A
attr_accessor :myvar
end

a = A.new
p a.myvar.class.to_s

NilClass

p a.myvar=2.class.to_s

Fixnum

p a.myvar=‘string’.class.to_s

String


Why does Ruby treat @myvar different from myvar?

Posted by unknown (Guest) on 04.04.2007 15:30
Exactly why it does that with instance variables and not with local variables
I don’t know, but they are used in different enough ways that the difference
should not be bothersome.

The answer:

Posted by Brian C. (Guest) on 04.04.2007 15:44
That’s because both method names and local variable names fall into the same name space


I thank again everyone :smiley:

My sister just asked me today “Who is Ruby, is she your girlfriend?” LOL

On Thu, Apr 05, 2007 at 03:49:15AM +0900, Jamal S. wrote:

puts @myvar.class.to_s

NilClass

puts does an implicit to_s on anything you pass to it, so you don’t
actually
need to do that explicitly.

puts @myvar=“string”.class.to_s

String

Careful here. This is the same as

puts @myvar=(“string”.class.to_s)

i.e. you are assigning “String” to @myvar, not “string”.

p a.myvar=2.class.to_s

Fixnum

Again, here the @myvar instance variable of ‘a’ now contains string
“Fixnum”

Regards,

Brian.

In article removed_email_address@domain.invalid,
Jamal S. removed_email_address@domain.invalid wrote:

if var.nil?

var is unknown?

it’s not variable, neither object? what is it? nobody knows, throw
exception to the bad coder :stuck_out_tongue:

Ruby variables aren’t quite what you expect. They are merely
labels that point to existing objects, they have no inhernet
existance in and of themselves. Ruby will “autocreate” objects
along the way, but IMHO it requires thinking about variables in
a much different way that most other languages use the term
variables.

Personally, I think this is a least an interesting if not good
thing. It requires that you think in different ways about how
variable work.

The problems you are having is that you are making method
calls on non-existant objects. It’s like handing a NULL pointer
in C to a function that expects a pointer.

_ Booker C. Bense

On Apr 4, 2007, at 2:49 PM, Jamal S. wrote:

It has been long topic now, and very helpful, I must admit I really
love
the Ruby Community, such Community is hard to find other places :slight_smile:

I want to thanks everyone very much :slight_smile:

It looks like things are a lot clearer for you now. Just a couple
comments on your summary:

The code below would not throw any exception:
puts @myvar

nil

Ruby already know whatever start with @ would be instance of
something,
if not then it would still be nil object, means false.

Start a brand new session of IRB and try:

irb> instance_variables
=> []
irb> @alpha
=> nil
irb> instance_variables
=> ["@alpha"]
irb> @beta = 42
=> 42
irb> instance_variables
=> ["@alpha", “@beta”]
irb> instance_variable_set("@gamma", ‘foo’)
=> “foo”
irb> instance_variables
=> ["@alpha", “@beta”, “@gamma”]

Instance variables come into existence when

  1. they appear on the left side of an assignment, in which case
    they are
    initialized to the value on the right hand side of the assignment
  2. when they are referenced in an expression, in which case they are
    initialized with a reference to the nil object.
  3. when they are set via a call to instance_variable_set()

The Accessors only provide you with the set and get properties similar
to other languages, when you declare something like this:
attr_accessor :myvar
You would have an instance of nil object.

This is a bit misleading. There is one and only one instance of
NilClass.
So it would be better to say:

You would have a reference to the nil object, which is an instance
of NilClass (the only instance).

All reference to ‘nil’ are references to the same object:

@a # force @a to exist
@b # force @b to exist

@a.object_id # 4
@b.object_id # 4
nil.object_id # 4

@a.equal?(nil) # true
@b.equal?(nil) # true
nil.equal?(nil) # true

I think the key thing to remember is that ‘nil’ is not a special
value that
indicates ‘no object’. Instead it is a special object that acts as a
sentinel.
There are a number of Ruby conventions that allow nil to act as a
powerful and
useful sentinel:

1) instance variables and global variables default to reference

the nil object.
2) The literal ‘nil’ always references the same object, the nil
object.
3) There is no way to create additional instances of NilClass.
4) All objects respond to the method: ‘nil?’
5) The nil object is the only object that responds with ‘true’
to ‘nil?’.
All other objects respond with ‘false’.
6) In a boolean context, ‘nil’ is considered false.

These properties enable such idioms as:

@foo ||= 'default'
@bar = first_choice || second_choice || third_choice

Ruby’s dynamic typing allows ‘nil’ to be used as a convenient
sentinel value for
many methods. For example ‘getc’ returns the next byte from an IO
stream as
an instance of Fixnum but if the end of the stream is encountered nil
is returned
instead of a special sentinel instance of Fixnum (e.g. -1 as in the C
programming
language).

Gary W.

Jamal S. wrote:

I thought keywords are class, def, end, which mean something to the
compiler only.

http://www.google.com/search?q=ruby+keywords

The first result is comically direct.

I did not think there would be something that behaved like a method
“defined?” which would be keyword?

Why not just make it a global method, put it in a module so nobody is
confused about that, because it looks like a method to me :slight_smile:

The reason why not is that when calling methods, Ruby always evaluates
the arguments first.[1] So saying defined? blahblah would fail,
because Ruby would try to evaluate blahblah, not find a blahblah method,
and raise a NoMethodError.

Now, you could make a defined method that took a String instead of a
bare word, e.g.:
def str_defined?(str) # cheap & ugly implementation
eval “defined?(#{str})”
# if you don’t want to use defined? there are other hooks
available:
# constants, local_variables, instance_variables, class_variables,
# global_variables
# Those guys are methods, magically defined by the interpreter.
end
str_defined? “blahblah”

There are method/keyword parallels in Ruby like this – define_method vs
def, alias_method vs alias, etc.

You could even use blocks to make something that looked like:
is_defined? { blahblah }
But that’s very much insane.

Ruby already know whatever start with @ would be instance of
something, if not then it would still be nil object, means false.
“instance variable” does not mean “instance of something,” but
explaining what is does mean would mean a rather long side-wind into
OOP.

Why does Ruby treat @myvar different from myvar?
BTW, you can emulate the @myvar way:
def method_missing(sym, *a, &b)
(!a.empty? || b) ? super : nil
end

a #=> nil
a = 5
a #=> 5

But, like, don’t do that.

Devin

[1] This differs from other languages like Lisp and Io – it probably
comes from its C heritage.

if a.nil?
p ‘thanks’;
end

class You
def self.method_missing(sym) puts “#{self}'re #{sym}.” end
end
You.welcome

Gary W. wrote:

On Apr 4, 2007, at 2:49 PM, Jamal S. wrote:

Thanks for your comment, now I understand that all the unused instance
variable would reference to the same object until they come into
existence:

  1. by assigement.
  2. by reference (as default to nil object)
  3. by using the object method instance_variable_set()

Brian C. wrote:

On Thu, Apr 05, 2007 at 03:49:15AM +0900, Jamal S. wrote:

puts does an implicit to_s on anything you pass to it, so you don’t actually
need to do that explicitly.

Thanks, now I know :slight_smile:

puts @myvar=“string”.class.to_s

String

Careful here. This is the same as

puts @myvar=(“string”.class.to_s)

True,
puts “string”.class


Thanks for the other replies :smiley:

Now the question is,

When does the instance variable holds the object itself?

class A; end;

@one = A.new
@two = A.new

p @one.object_id
p @one_object_id

21103660

21103640

Two different objects, even if they were the same.

How does all the nil instance variable reference to the same object?

On 4/4/07, Gary W. removed_email_address@domain.invalid wrote:

irb> instance_variables
=> [“@alpha”, “@beta”]
irb> instance_variable_set(“@gamma”, ‘foo’)
=> “foo”
irb> instance_variables
=> [“@alpha”, “@beta”, “@gamma”]

Not quite:irb(main):001:0> instance_variables
=> []
irb(main):002:0> @alpha
=> nil
irb(main):003:0> instance_variables
=> []
irb(main):004:0> @beta = 42
=> 42
irb(main):005:0> instance_variables
=> [“@beta”]
irb(main):006:0> defined? @alpha
=> nil
irb(main):007:0> defined? @beta
=> “instance-variable”

Instance variables come into existence when

  1. they appear on the left side of an assignment, in which case
    they are
    initialized to the value on the right hand side of the assignment
    Yes
  2. when they are referenced in an expression, in which case they are
    initialized with a reference to the nil object.

No, they are not initialized (or even defined) at this point. They
just evaluate syntactically to nil. See line 6 above.

  1. when they are set via a call to instance_variable_set()

Yes.

Note that the result of the defined? operator is a syntactic
description of the argument.

In line 6 above defined? @alpha is not saying that the value of
@alpha is nil, but that since it @alpha isn’t defined, there’s no
description, and since nil is treated as false in Ruby logical
expressions and anything other than nil and false is treated as true
you can do things like
p @alpha if defined? @alpha

Here’s another subtlety:
irb(main):008:0> defined? nil
=> “nil”

Note that it’s not returning the value nil, but the descriptive string
“nil”.

From the ruby 1.8.5 source, the values which defined? can return are
“assignment”, “class variable”, “constant”, “expression”,
“global-variable”, “instance-variable”, “local-variable”,
“local-variable(in-block)”, “false”, “method”, “self”, “super”,
“true”, “yield”, and nil

It can also return things like “$1”, “$2” etc. and “$$”, “$`”, “$/”,
“$'”, and “$+” for regexp match references. These are only defined
after a regexp match which sets them, until a regexp match which
doesn’t.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Gary W. wrote:

On Apr 6, 2007, at 9:24 AM, Jamal S. wrote:

Two different objects, even if they were the same.
Do you have a typo there? Do you want:

p @one.object_id
p @two.object_id

I thought that if both @instance don’t have the same object_id they
would two different objects…but that is not true?

On Apr 6, 2007, at 9:24 AM, Jamal S. wrote:

When does the instance variable holds the object itself?

Instance variables never hold the objects themselves.
Ruby variables always hold references to objects.

Note: It is often explained that in some special cases
Ruby variables hold ‘immediate values’. Such as small
integers as Fixnum instances and the unique objects
nil, false, and true. I think that this is an
unnecessary complication. It is easier and more
consistent to always talk about references. In
particular assignment is always about copying a
reference and never about duplicating an object
or a value:

a = 1 # 1 is a reference to a Fixnum
# now a references the same fixnum
b = a # b now references the same fixnum as a

a = “foo” # a is a reference to a string instance
b = a # b now references the same string as a

The ‘trick’ is to think of literals (-1,0,1,nil,true,false, etc.)
as references and not as values or objects.

I’d almost go as far to say that in Ruby there is only
one type of value, an object reference. Assignment, method
argument passing and return values are all about the copying
of references and not at all about objects.

Two different objects, even if they were the same.
Do you have a typo there? Do you want:

p @one.object_id
p @two.object_id

These are two different objects and so they have two
different object ids. I’m not sure what your question
is here.

How does all the nil instance variable reference to the same object?

Can you rephrase the question? I’m not sure what you are asking.

@a = nil
@b = @a
@c = @b

All three instance variables now reference the same object. It
is the same object referenced by the literal, nil. Don’t think
of ‘nil’ as an object. Think of it as a reference to a particular
distinguished object.

On Apr 6, 2007, at 2:56 PM, Jamal S. wrote:

I thought that if both @instance don’t have the same object_id they
would two different objects…but that is not true?

That is true. All objects have unique object ids. If the objects
referenced by two variables have the same object id then you’ve got
two references to the same object.

In your original post you had:

@one = A.new
@two = A.new

p @one.object_id
p @one_object_id # TYPO???

21103660

21103640

Which just doesn’t make sense. Specifically, @one_object_id isn’t
defined in your example (note the underscore instead of dot)
and should have evaluated to nil. Since you illustrated two
different object_id’s, I assumed you had simply made
some sort of cut and paste error and you had intended to show
@two.object_id and not @one_object_id.

On Apr 6, 2007, at 2:24 PM, Rick DeNatale wrote:

  1. when they are referenced in an expression, in which case
    they are
    initialized with a reference to the nil object.

No, they are not initialized (or even defined) at this point. They
just evaluate syntactically to nil. See line 6 above.

Thanks for the correction. I could have sworn that I tested that code
before posting to make sure I understood what was going on. Maybe I
had some left over variables from earlier in the irb session.

So it is only assignment and instance_variable_set that will cause
an instance variable to become defined and bound to a reference.

Undefined instance variables evaluate to nil.

Gary W.

On Sat, Apr 07, 2007 at 06:23:50PM +0900, Brian C. wrote:

@two = A.new
it is wrong.
assigning to an instance variable of a top-level session object called
‘main’

A longer way of writing it would have been:

main.instance_variable_set(:@one, Foo.new)

Then assigning to @two you’ll get another object reference stored there.

Clearly then, puts @one.object_id and puts @two.object_id will show you
distinct references to the two distinct objects you created.

If you want two separate names for the same object with the same object
ID (aka the same object_id), you could chain assignments together:

irb(main):003:0> three = four = A.new
=> #<A:0x80566b4>
irb(main):004:0> three.object_id === four.object_id
=> true
irb(main):005:0> p three.object_id
67285850
=> nil
irb(main):006:0> p four.object_id
67285850
=> nil