What is the purpose of an anonymous structure in Ruby?

They can be defined as follows

Struct.new(:x, :y)

But what can be done profitably with them? In particular, how can I create an instance of such a structure? This does not work.

Struct.new(:x => 1, :y => 1)

(you get TypeError: can't convert Hash into String ).

I am using Ruby 1.9.2.

UPDATE:

Good pointers for now, thanks. I suppose the reason I asked about this was because I found several times that I wanted to do this.

Struct.new(:x => 1, :y => 1)

so that I can pass the object around where I can write obj.x instead of, say, creating a hash instance and writing obj[:x] . In this case, I want the structure to be truly anonymous - I do not want to pollute my namespace with anything, calling what is returned from the call to Struct.new . The closest to this, as already mentioned,

Struct.new(:x, :y).new(1, 1)

But how do you like apples? I'm not sure I know. Can one expect to be able to define and instantiate an anonymous structure at a time (as part of the core Ruby)? I think when I read the official Ruby Struct.new on Struct.new , I assume that the word “anonymous” allows it, but it doesn’t.

+4
source share
6 answers

Struct.new returns a Class , so you can, for example, assign it to a constant as follows:

 Point = Struct.new(:x, :y) 

or subclass:

 class Point < Struct.new(:x, :y) # custom methods here # ... end 

In both cases, you can use the resulting class as follows:

 Point.new(3, 5) 

If you do not want to create a specific class (because you need to instantiate an object of this class only once), consider OpenStruct instead:

 require 'ostruct' point = OpenStruct.new(:x => 3, :y => 5) 
+18
source

Well, you can use Structs when you really don't want to write a class using accessories. It’s convenient just to write

 Project = Struct.new(:name) 

instead

 class Project attr_accesor :name end 

As Tokland correctly pointed out (thanks!), Struct also gives you a great #initialize method automatically. Thus, without additional code, the following is possible:

 Project = Struct.new(:name) p = Project.new('Quadriloptic Curves') 
+4
source

First you create a structure, and then you can create instances of it. This is a way to create data objects without declaring a class. This is basically the same as a hash, but it is cleaner to access objects. You can get material from it by referencing it using regular access methods.

http://www.ruby-doc.org/core-1.9.3/Struct.html

 # Create a structure with a name in Struct Struct.new("Customer", :name, :address) #=> Struct::Customer Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main"> # Create a structure named by its constant Customer = Struct.new(:name, :address) #=> Customer Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main"> 
+3
source

I am very confident in the goal, but Struct.new returns the class, so

 irb(main):001:0> Struct.new(:x,:y) => #<Class:0x2914110> irb(main):002:0> Struct.new(:x,:y).new(1,2) => #<struct x=1, y=2> 
+2
source

Regarding instantiation:

 User = Struct.new(:user,:password) u = User.new("john","secret") 
0
source

OpenStruct is probably what you want, but I came across a situation recently when OpenStruct did not work, because I needed to raise an error when trying to access the undefined attribute. Struct does the following:

 os = OpenStruct.new os.x = 1; os.y = 2; os.z # returns nil s = Struct.new(:x, :y).new sx = 1; sy = 2; sz # raises NoMethodError 

Just something to keep in mind.

0
source

Source: https://habr.com/ru/post/1387550/


All Articles