Confusion with Struct class

I went to there - http://www.ruby-doc.org/core-2.0/Struct.html but the
below mentioned not cleared.

Customer = Struct.new(:name, :address)
p Customer.class #=>class

Struct.new("Customer", :name, :address)
p Customer.class #`<main>': uninitialized constant Customer (NameError)

Can anyone help me what's the difference between these two construct?

···

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

If you read the doc you referenced closely:

"Creates a new class, named by aString, containing accessor methods
for the given symbols. If the name aString is omitted, an anonymous
structure class will be created. Otherwise, ***the name of this struct
will appear as a constant in class Struct***, so it must be unique for
all Structs in the system and should start with a capital letter.
Assigning a structure class to a constant effectively gives the class
the name of the constant."

Check the part between ***

1.9.2p290 :001 > Struct.new("Customer", :name, :address)
=> Struct::Customer
1.9.2p290 :002 > p Struct::Customer
Struct::Customer
=> Struct::Customer
1.9.2p290 :003 > p Struct::Customer.class
Class
=> Class

Jesus.

···

On Thu, Apr 11, 2013 at 10:45 AM, Love U Ruby <lists@ruby-forum.com> wrote:

I went to there - Class: Struct (Ruby 2.0.0) but the
below mentioned not cleared.

Customer = Struct.new(:name, :address)
p Customer.class #=>class

Struct.new("Customer", :name, :address)
p Customer.class #`<main>': uninitialized constant Customer (NameError)

Can anyone help me what's the difference between these two construct?

Thanks @Matthew and @Jesús.

Customer = Struct.new(:name, :address)

  and

Struct.new("Customer", :name, :address)

Is both the declaration will work same way? Means any more differences
with the above two approaches?

Thanks

···

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

Why does every time the has value getting changed,while the instance
variables values are not getting changed?

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

p joe.hash
p joe.object_id

#-93880937
#8577648

p joe.hash
p joe.object_id

#275982710
#8577648

p joe.hash
p joe.object_id

#767998854
#8577648

···

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

Here is another confusion:

I tried the below code:

···

===============================
Customer = Struct.new(:name, :address) do |x|
  def x.greeting
    "Hello #{name}!"
  end
end

p Customer.greeting #=> "Hello Customer!"

Now my question is - How does instance variable has been assigned to
`Customer`?

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

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1105232:

If you read the doc you referenced closely:

***the name of this struct

will appear as a constant in class Struct***,

Yes,I am confused how a full class be a constant. We can create a
variable as a constant, say "NAME". class and module names are also
constant. But full class body is constant - I just newly step into this
topic.

···

On Thu, Apr 11, 2013 at 10:45 AM, Love U Ruby <lists@ruby-forum.com> > wrote:

1.9.2p290 :001 > Struct.new("Customer", :name, :address)
=> Struct::Customer
1.9.2p290 :002 > p Struct::Customer
Struct::Customer
=> Struct::Customer
1.9.2p290 :003 > p Struct::Customer.class
Class
=> Class

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

Thanks @Matthew and @Jesús.

Customer = Struct.new(:name, :address)

and

Struct.new("Customer", :name, :address)

Is both the declaration will work same way? Means any more differences
with the above two approaches?

Thanks

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

Customer = Struct.new(:name, :address)

You'll have to use Customer.new to create new customers, but in:

Struct.new("Customer", :name, :address)

It'll register the Customer class inside the Struct class, so you'll have to refer to it like this:

Struct::Customer.new

Struct is a class that GENERATES other classes for you. The syntax where you pass in the name of the class registers the new class inside the struct class... the other syntax doesn't, it just registers it against whatever you assign it to.

Point in case:

x = Struct.new(:name, :address)

=> #<Class:0x007fbcea91ed68>

x.new

=> #<struct name=nil, address=nil>

Julian

···

On 11/04/2013, at 11:59 PM, Love U Ruby <lists@ruby-forum.com> wrote:

What the heck are you doing?

irb(main):004:0> Customer = Struct.new(:name, :address, :zip)
=> Customer
irb(main):005:0> joe = Customer.new("Joe Smith", "123 Maple, Anytown NC",
12345)
=> #<struct Customer name="Joe Smith", address="123 Maple, Anytown NC",
zip=12345>
irb(main):006:0> 5.times { puts joe.hash }
1060632465
1060632465
1060632465
1060632465
1060632465
=> 5
irb(main):007:0> 5.times { puts Customer.new("Joe Smith", "123 Maple,
Anytown NC", 12345).hash }
1060632465
1060632465
1060632465
1060632465
1060632465
=> 5

robert

···

On Thu, Apr 11, 2013 at 4:27 PM, Love U Ruby <lists@ruby-forum.com> wrote:

Why does every time the has value getting changed,while the instance
variables values are not getting changed?

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

p joe.hash
p joe.object_id

#-93880937
#8577648

p joe.hash
p joe.object_id

#275982710
#8577648

p joe.hash
p joe.object_id

#767998854
#8577648

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Huh? what are you asking?

···

----- Original Message -----
From: Love U Ruby <lists@ruby-forum.com>

Now my question is - How does instance variable has been assigned to
`Customer`?

The object x that is passed into the block is the class that is being
created by Struct. When you define x.greeting, this is a singleton
method on the class object, and when inside that method you call
"name", you are actually calling a method of the x object, which is
class. With this test, you have discovered that classes have a "name"
method, that contains the constant to which they are assigned (this is
done either when doing class X, or X = <a class>):

1.9.2p290 :008 > Customer.methods
=> [...:name,...]

As you can see the class Customer has a name method.

If you create a class without assigning it to a constant, it doesn't
have a name:

1.9.2p290 :009 > c = Class.new
=> #<Class:0x00000002519990>
1.9.2p290 :010 > c.name
=> nil

on the other hand:

1.9.2p290 :011 > C = Class.new
=> C
1.9.2p290 :012 > C.name
=> "C"

and

1.9.2p290 :013 > class D
1.9.2p290 :014?> end
=> nil
1.9.2p290 :015 > D.name
=> "D"

Hope this helps,

Jesus.

···

On Thu, Apr 11, 2013 at 7:38 PM, Love U Ruby <lists@ruby-forum.com> wrote:

Here is another confusion:

I tried the below code:

===============================
Customer = Struct.new(:name, :address) do |x|
  def x.greeting
    "Hello #{name}!"
  end
end

p Customer.greeting #=> "Hello Customer!"

Now my question is - How does instance variable has been assigned to
`Customer`?

Love U Ruby wrote in post #1105300:

===============================
Customer = Struct.new(:name, :address) do |x|
  def x.greeting
    "Hello #{name}!"
  end
end

p Customer.greeting #=> "Hello Customer!"

You probably intended to write:

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end

This will create a method named "greeting" on ALL of your Customer
structs. It's a neat trick, since the method won't be seen as a member
of the struct.

I like even more that you can include a module:

module Greeter
  def greeting
    "Hello #{name}!"
  end
end

Customer = Struct.new(:name, :address) do
  include Greeter
end

···

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

Remember that all ruby values are objects, even classes.

    # classes
    class Foo; end
    Bar = class.new
    $baz = Foo
    qux = Bar

    # instance objects
    Foo.new
    Bar.new
    $baz.new
    qux.new

It's all, mostly, the same.

And a 'constant' is just a variable that gets a special warning when
assgined to, but aside from that it's not particularly magical.

    MyConst =
    # all good:
    MyConst << 1
    MyConst.unshift 7
    MyConst.sort!
    MyConst.delete_if { |e| e<3 }
    def MyConst.foo; end
    # not good:
    MyConst = [7]

You can modify the _object_, but you can't modify the reference.

···

On Apr 11, 2013 8:19 PM, "Love U Ruby" <lists@ruby-forum.com> wrote:

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1105232:
> On Thu, Apr 11, 2013 at 10:45 AM, Love U Ruby <lists@ruby-forum.com> > > wrote:
>>
> If you read the doc you referenced closely:
>
***the name of this struct
> will appear as a constant in class Struct***,

Yes,I am confused how a full class be a constant. We can create a
variable as a constant, say "NAME". class and module names are also
constant. But full class body is constant - I just newly step into this
topic.

1.9.2p290 :001 > class S
1.9.2p290 :002?> Foo = Class.new
1.9.2p290 :003?> end
=> S::Foo
1.9.2p290 :004 > S::Foo
=> S::Foo

A class can have constants inside. Those constants can reference any
object, for example a Class.
There's nothing really more to it than this. You refer to a constant
inside a class with the :: syntax as shown above.

Jesus.

···

On Thu, Apr 11, 2013 at 12:19 PM, Love U Ruby <lists@ruby-forum.com> wrote:

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1105232:

On Thu, Apr 11, 2013 at 10:45 AM, Love U Ruby <lists@ruby-forum.com> >> wrote:

If you read the doc you referenced closely:

***the name of this struct

will appear as a constant in class Struct***,

Yes,I am confused how a full class be a constant. We can create a
variable as a constant, say "NAME". class and module names are also
constant. But full class body is constant - I just newly step into this
topic.

Robert Klemme wrote in post #1105267:

irb(main):006:0> 5.times { puts joe.hash }
1060632465
1060632465
1060632465
1060632465
1060632465
=> 5

For me now it is also OK. I don't know why I got such bullshit output
earlier?

p RUBY_VERSION
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
p 5.times { puts joe.hash }
p joe.hash
p joe.hash

Output:

"1.9.3"
-672312861
-672312861
-672312861
-672312861
-672312861
5
-672312861
8577108
-672312861
8577108

···

On Thu, Apr 11, 2013 at 4:27 PM, Love U Ruby <lists@ruby-forum.com> > wrote:

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

Wayne Brisette wrote in post #1105303:

···

----- Original Message -----
From: Love U Ruby <lists@ruby-forum.com>

Now my question is - How does instance variable has been assigned to
`Customer`?

Huh? what are you asking?

How "Hello #{name}!" evaluated to "Hello Customer!" ?

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

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1105307:

···

On Thu, Apr 11, 2013 at 7:38 PM, Love U Ruby <lists@ruby-forum.com> > wrote:

As you can see the class Customer has a name method.

If you create a class without assigning it to a constant, it doesn't
have a name:

1.9.2p290 :009 > c = Class.new
=> #<Class:0x00000002519990>
1.9.2p290 :010 > c.name
=> nil

on the other hand:

1.9.2p290 :011 > C = Class.new
=> C
1.9.2p290 :012 > C.name
=> "C"

Really a new lesson for me. thank you very much for such an great
explanation. At least an impressive difference between `c=Class.new` and
`C=Class.new` object instantiation technique.

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

Correct me if i'm wrong, but since when ruby 1.9 uses "name" for class name? I always though that it's Class.new.class.name or Class.class.name that gives proper result.

I've looked at ruby source, and it looks that in ruby 1.9.3 it references module name, but the constant namespace have some side effect on it.

···

On Apr 11, 2013, at 9:14 PM, Jesús Gabriel y Galán wrote:

On Thu, Apr 11, 2013 at 7:38 PM, Love U Ruby <lists@ruby-forum.com> wrote:

Here is another confusion:

I tried the below code:

===============================
Customer = Struct.new(:name, :address) do |x|
def x.greeting
   "Hello #{name}!"
end
end

p Customer.greeting #=> "Hello Customer!"

Now my question is - How does instance variable has been assigned to
`Customer`?

The object x that is passed into the block is the class that is being
created by Struct. When you define x.greeting, this is a singleton
method on the class object, and when inside that method you call
"name", you are actually calling a method of the x object, which is
class. With this test, you have discovered that classes have a "name"
method, that contains the constant to which they are assigned (this is
done either when doing class X, or X = <a class>):

1.9.2p290 :008 > Customer.methods
=> [...:name,...]

As you can see the class Customer has a name method.

If you create a class without assigning it to a constant, it doesn't
have a name:

1.9.2p290 :009 > c = Class.new
=> #<Class:0x00000002519990>
1.9.2p290 :010 > c.name
=> nil

on the other hand:

1.9.2p290 :011 > C = Class.new
=> C
1.9.2p290 :012 > C.name
=> "C"

and

1.9.2p290 :013 > class D
1.9.2p290 :014?> end
=> nil
1.9.2p290 :015 > D.name
=> "D"

Hope this helps,

Jesus.

In other words: Struct generated classes are ordinary classes and the block
passed to Struct.new is a class body as is the one passed to Class.new - no
surprises here. :slight_smile:

irb(main):001:0> c=Class.new do
irb(main):002:1* def foo; 123 end
irb(main):003:1> end
=> #<Class:0x8335bb4>
irb(main):004:0> c.new.foo
=> 123

Kind regards

robert

···

On Thu, Apr 18, 2013 at 11:41 PM, Scott Shaffer <lists@ruby-forum.com>wrote:

I like even more that you can include a module:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

That output doesn't fit the program. Where do lines with "8577108" come
from?

Also "p 5.times ..." doesn't make sense.

robert

···

On Thu, Apr 11, 2013 at 4:59 PM, Love U Ruby <lists@ruby-forum.com> wrote:

Robert Klemme wrote in post #1105267:
> On Thu, Apr 11, 2013 at 4:27 PM, Love U Ruby <lists@ruby-forum.com> > > wrote:
>

> irb(main):006:0> 5.times { puts joe.hash }
> 1060632465
> 1060632465
> 1060632465
> 1060632465
> 1060632465
> => 5

For me now it is also OK. I don't know why I got such bullshit output
earlier?

p RUBY_VERSION
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
p 5.times { puts joe.hash }
p joe.hash
p joe.hash

Output:

"1.9.3"
-672312861
-672312861
-672312861
-672312861
-672312861
5
-672312861
8577108
-672312861
8577108

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Alex Newone wrote in post #1105332:

Correct me if i'm wrong, but since when ruby 1.9 uses "name" for class
name? I always though that it's Class.new.class.name or Class.class.name
that gives proper result.

As Jesus said: "The object x that is passed into the block is the class
that is being created by Struct."

E.g.:
  irb(main):001:0> Foo = Struct.new(:a) {|x| p [x, x.class] }
  [#<Class:0x0000000287a5a8>, Class]
  => Foo

So my `x` is the actual `Foo` class object, not an instance of it. Thus
the following are effectively equivalent:

  Foo = Struct.new(:a) do |x|
    def x.bar
      "#{name}bar"
    end
  end

  class Foo
    attr_accessor :a
    def Foo.bar
      "#{name}bar"
    end
  end

You can see that `name` is being called on the object on which the
method Foo is defined, which is the object Foo, which is an instance of
Class.

···

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