Struct

Hi

Is there any possibility to remove (undo) a Struct.new("NAME",...),
   because Struct::NAME exists after that, setting to nil doesn't help

thanks
Opti

Have you looked at remove_const?

20:36 $ irb
irb(main):001:0> Struct.new("NAME")
=> Struct::NAME
irb(main):002:0> Struct::NAME
=> Struct::NAME
irb(main):003:0> Struct.send(:remove_const, "NAME")
=> Struct::NAME
irb(main):004:0> Struct::NAME
NameError: uninitialized constant Struct::NAME
        from (irb):4
        from /Users/mike/.rbenv/versions/2.3.3/bin/irb:11:in `<main>’

Hope this helps,

Mike

···

On Jan 7, 2017, at 8:26 PM, Die Optimisten <inform@die-optimisten.net> wrote:

Hi

Is there any possibility to remove (undo) a Struct.new("NAME",...),
because Struct::NAME exists after that, setting to nil doesn't help

thanks
Opti

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

This form of Struct.new creates all Struct classes in the same
namespace Struct. I usually do not use that form of Struct.new - I
prefer to assign a class name explicitly because then I have control
over the namespace and can avoid namespace clashes:

module MyModule
  MyClass = Struct.new :field1, :field2, :etc
end

I would go as far as to suggest to deprecate the Struct.new with a
String as first argument because of the said issues.

Kind regards

robert

···

On Sun, Jan 8, 2017 at 2:26 AM, Die Optimisten <inform@die-optimisten.net> wrote:

Is there any possibility to remove (undo) a Struct.new("NAME",...),
  because Struct::NAME exists after that, setting to nil doesn't help

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Hi!
Yes, also doku says "don't use this", but I'm trying to make a class which generates different structs,
which are later filled with contents in another class.
So I can't depend on the (constant) name (defined in the class-code), it should be variable, so Struct(string,...) would be very indeed very handy.
Better to write an own struct-class from the very beginning?
Any idea how to best emulate @MyStruct=Struct.new(namevar, ... ) without that arg0?

Is @S the "same" (usage) as @s (no constant); also with @@S2 and @@s2 ?

Where do I find the real code for Struct, ri shows only "stub for Struct.new, stub for <all>" ?

Thanks also Mike for that info!

Opti

···

On 2017-01-08 10:04, Robert Klemme wrote:

On Sun, Jan 8, 2017 at 2:26 AM, Die Optimisten > <inform@die-optimisten.net> wrote:

Is there any possibility to remove (undo) a Struct.new("NAME",...),
   because Struct::NAME exists after that, setting to nil doesn't help

This form of Struct.new creates all Struct classes in the same
namespace Struct. I usually do not use that form of Struct.new - I
prefer to assign a class name explicitly because then I have control
over the namespace and can avoid namespace clashes:

module MyModule
   MyClass = Struct.new :field1, :field2, :etc
end

I would go as far as to suggest to deprecate the Struct.new with a
String as first argument because of the said issues.

Kind regards

robert

Is there any possibility to remove (undo) a Struct.new("NAME",...),
   because Struct::NAME exists after that, setting to nil doesn't help

This form of Struct.new creates all Struct classes in the same
namespace Struct. I usually do not use that form of Struct.new - I
prefer to assign a class name explicitly because then I have control
over the namespace and can avoid namespace clashes:

module MyModule
   MyClass = Struct.new :field1, :field2, :etc
end

I would go as far as to suggest to deprecate the Struct.new with a
String as first argument because of the said issues.

Kind regards

robert

Hi!
Yes, also doku says "don't use this", but I'm trying to make a class which
generates different structs,
which are later filled with contents in another class.
So I can't depend on the (constant) name (defined in the class-code), it
should be variable, so Struct(string,...) would be very indeed very handy.

Then you could stuff them into a Hash or generate constant names. But
the latter has the advantage that you also have to resort to const_get
when accessing. So you can put these classes in a Hash right away.

Better to write an own struct-class from the very beginning?

Rather not.

Any idea how to best emulate @MyStruct=Struct.new(namevar, ... ) without
that arg0?

See above.

Is @S the "same" (usage) as @s (no constant); also with @@S2 and @@s2 ?

No, Ruby is case sensitive.

Where do I find the real code for Struct, ri shows only "stub for
Struct.new, stub for <all>" ?

C source code.

robert

···

On Sun, Jan 8, 2017 at 1:08 PM, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-08 10:04, Robert Klemme wrote:

On Sun, Jan 8, 2017 at 2:26 AM, Die Optimisten >> <inform@die-optimisten.net> wrote:

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Where do I find the real code for Struct, ri shows only "stub for
Struct.new, stub for <all>" ?

C source code.

https://github.com/ruby/ruby/blob/trunk/struct.c

But you can have a look at a Ruby implentation of Struct at the
Rubinius source code if you want.

Abinoam Jr.

Is @S the "same" (usage) as @s (no constant); also with @@S2 and @@s2 ?

No, Ruby is case sensitive.

Hi!
I meant no constant. At this view there is no difference?
(a is the same as aa, but NOT as A;
but @a is the same as @B, and @@C the same as @@d)

Opti

Hi

I want to rename a method:
class Struct
     alias fields members
end

Why does this not work? How to do it correctly?

Thanks
Opti

It does work.

irb(main):001:0> S = Struct.new(:foo, :bar)
=> S
irb(main):002:0> S.new.members
=> [:foo, :bar]
irb(main):003:0> S.new.fields
NoMethodError: undefined method `fields' for #<struct S foo=nil, bar=nil>
from (irb):3
from /usr/bin/irb:11:in `<main>'
irb(main):004:0> class Struct; alias fields members; end
=> nil
irb(main):005:0> S.new.fields
=> [:foo, :bar]

···

On Mon, Jan 9, 2017 at 12:18 AM, Die Optimisten <inform@die-optimisten.net> wrote:

I want to rename a method:
class Struct
    alias fields members
end

Why does this not work? How to do it correctly?

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

You could define an instance variable @FOO, but by convention
instance variables are lower case, similar to local variables.

So: use @foo for an instance variable, FOO for a constant.

Note also that one-letter variable names are usually frowned
upon in the community (with exceptions, of course).

Regards,
Marcus

···

Am 08.01.2017 um 23:45 schrieb Die Optimisten:

Is @S the "same" (usage) as @s (no constant); also with @@S2 and @@s2 ?

No, Ruby is case sensitive.

Hi!
I meant no constant. At this view there is no difference?
(a is the same as aa, but NOT as A;

--
GitHub: https://github.com/stomar/
PGP: 0x6B3A101A

Hi
I tried

class Struct
     alias fields members
end
S=Struct.new(:a)
S.fields # S.members does it!

How can I do that?
(with def, if alias is not working for this)

thanks
Opti

···

On 2017-01-09 08:18, Robert Klemme wrote:

On Mon, Jan 9, 2017 at 12:18 AM, Die Optimisten > <inform@die-optimisten.net> wrote:

I want to rename a method:
class Struct
     alias fields members
end

Why does this not work? How to do it correctly?

It does work.

irb(main):001:0> S = Struct.new(:foo, :bar)
=> S
irb(main):002:0> S.new.members
=> [:foo, :bar]
irb(main):003:0> S.new.fields
NoMethodError: undefined method `fields' for #<struct S foo=nil, bar=nil>
from (irb):3
from /usr/bin/irb:11:in `<main>'
irb(main):004:0> class Struct; alias fields members; end
=> nil
irb(main):005:0> S.new.fields
=> [:foo, :bar]

​You're using the alias to set up an instance method, then invoking a class
method. That never works.

I was going to write a big illustration to point you in the right direction
without giving the answer, but I think an answer might actually be more
useful. Note that there's no `Struct.members` method, so you can't use it
as a basis for anything.

···

On 9 January 2017 at 20:28, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-09 08:18, Robert Klemme wrote:

On Mon, Jan 9, 2017 at 12:18 AM, Die Optimisten >> <inform@die-optimisten.net> wrote:

I want to rename a method:

class Struct
     alias fields members
end

Why does this not work? How to do it correctly?

It does work.

irb(main):001:0> S = Struct.new(:foo, :bar)
=> S
irb(main):002:0> S.new.members
=> [:foo, :bar]
irb(main):003:0> S.new.fields
NoMethodError: undefined method `fields' for #<struct S foo=nil, bar=nil>
from (irb):3
from /usr/bin/irb:11:in `<main>'
irb(main):004:0> class Struct; alias fields members; end
=> nil
irb(main):005:0> S.new.fields
=> [:foo, :bar]

Hi
I tried

class Struct
    alias fields members
end
S=Struct.new(:a)
S.fields # S.members does it!

How can I do that?
(with def, if alias is not working for this)

thanks
Opti

~~~
irb(main):001:0> class Struct
irb(main):002:1> alias fields members # this works for instances
irb(main):003:1> def self.fields # this works for classes
irb(main):004:2> members
irb(main):005:2> end
irb(main):006:1> end
irb(main):007:0> S = Struct.new :a
irb(main):008:0> S.new.fields # from line 002:1
=> [:a]
irb(main):009:0> S.fields # from line 003:1
=> [:a]
irb(main):010:0> # NB:
irb(main):011:0* Struct.fields
NameError: undefined local variable or method `members' for Struct:Class
from (irb):4:in `fields'
from (irb):11
from /usr/local/bin/irb:11:in `<main>'
~~~

Or, if you desperately want to use aliases and avoid the extra level in the
call stack, you need to define the alias on each subclass:

~~~
irb(main):001:0> class Struct
irb(main):002:1> alias fields members # for instances
irb(main):003:1> end
irb(main):004:0> S = Struct.new(:a) do
irb(main):005:1* class <<self
irb(main):006:2> alias fields members # only for 'S'
irb(main):007:2> end
irb(main):008:1> end
irb(main):009:0> S.new.fields # from line 002:1
=> [:a]
irb(main):010:0> S.fields # from line 006:2
=> [:a]
irb(main):011:0> # Also:
irb(main):012:0* Struct.fields
NoMethodError: undefined method `fields' for Struct:Class
from (irb):12
from /usr/local/bin/irb:11:in `<main>'
~~~

You can even write it more compactly, but it's a bit horrible:

~~~
irb(main):001:0> class <<(S = Struct.new :a)
irb(main):002:1> alias fields members
irb(main):003:1> end
irb(main):004:0> S.fields
=> [:a]
~~~

Of course the even-more-correct answer is: don't do that. What's so wrong
with the name "members" that you feel the need to go to all this effort to
introduce bizarre idiosyncrasies - and possible incompatibilities - into
your code?

Cheers
--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Hi
Thanks for this long answer -
Why I'm doing this: I want to understand Ruby! -> Whats a good source of informationn / book for learning this?
Isn't it possible to "alias" (define) a class method .fields for the _class_-method .members?
without doing it by using the object-method?
S=STruct.new(:a)
S.membes # looks like a class method!
S.new.members # object-method, I don't want to use that
=> the best solution could be
class Struct
def self.fields
   self.members
end

Is that good to use?
Also considering the answer from Andy, is it depricated to use class-variabels?
(and instead use object-vars of a super-class)??

Thanks
Opti

···

On 2017-01-09 12:21, Matthew Kerwin wrote:

On 9 January 2017 at 20:28, Die Optimisten <inform@die-optimisten.net > <mailto:inform@die-optimisten.net>> wrote:

    On 2017-01-09 08:18, Robert Klemme wrote:

        On Mon, Jan 9, 2017 at 12:18 AM, Die Optimisten > <inform@die-optimisten.net <mailto:inform@die-optimisten.net>> > wrote:

            I want to rename a method:
            class Struct
                 alias fields members
            end

            Why does this not work? How to do it correctly?

        It does work.

        irb(main):001:0> S = Struct.new(:foo, :bar)
        => S
        irb(main):002:0> S.new.members
        => [:foo, :bar]
        irb(main):003:0> S.new.fields
        NoMethodError: undefined method `fields' for #<struct S
        foo=nil, bar=nil>
        from (irb):3
        from /usr/bin/irb:11:in `<main>'
        irb(main):004:0> class Struct; alias fields members; end
        => nil
        irb(main):005:0> S.new.fields
        => [:foo, :bar]

    Hi
    I tried

    class Struct
        alias fields members
    end
    S=Struct.new(:a)
    S.fields # S.members does it!

    How can I do that?
    (with def, if alias is not working for this)

    thanks
    Opti

​ You're using the alias to set up an instance method, then invoking a class method. That never works.

I was going to write a big illustration to point you in the right direction without giving the answer, but I think an answer might actually be more useful. Note that there's no `Struct.members` method, so you can't use it as a basis for anything.

~~~
irb(main):001:0> class Struct
irb(main):002:1> alias fields members # this works for instances
irb(main):003:1> def self.fields # this works for classes
irb(main):004:2> members
irb(main):005:2> end
irb(main):006:1> end
irb(main):007:0> S = Struct.new :a
irb(main):008:0> S.new.fields # from line 002:1
=> [:a]
irb(main):009:0> S.fields # from line 003:1
=> [:a]
irb(main):010:0> # NB:
irb(main):011:0* Struct.fields
NameError: undefined local variable or method `members' for Struct:Class
from (irb):4:in `fields'
from (irb):11
from /usr/local/bin/irb:11:in `<main>'
~~~

Or, if you desperately want to use aliases and avoid the extra level in the call stack, you need to define the alias on each subclass:

~~~
irb(main):001:0> class Struct
irb(main):002:1> alias fields members # for instances
irb(main):003:1> end
irb(main):004:0> S = Struct.new(:a) do
irb(main):005:1* class <<self
irb(main):006:2> alias fields members # only for 'S'
irb(main):007:2> end
irb(main):008:1> end
irb(main):009:0> S.new.fields # from line 002:1
=> [:a]
irb(main):010:0> S.fields # from line 006:2
=> [:a]
irb(main):011:0> # Also:
irb(main):012:0* Struct.fields
NoMethodError: undefined method `fields' for Struct:Class
from (irb):12
from /usr/local/bin/irb:11:in `<main>'
~~~

You can even write it more compactly, but it's a bit horrible:

~~~
irb(main):001:0> class <<(S = Struct.new :a)
irb(main):002:1> alias fields members
irb(main):003:1> end
irb(main):004:0> S.fields
=> [:a]
~~~

Of course the even-more-correct answer is: don't do that. What's so wrong with the name "members" that you feel the need to go to all this effort to introduce bizarre idiosyncrasies - and possible incompatibilities - into your code?

Cheers
--
  Matthew Kerwin
http://matthew.kerwin.net.au/

- Here is my code, to get an idea what I'm thinking of,
please add / correct, tell me what could be done better!

thanks!!
- Opti

class MyStruct < Array
   def self.fields
     @fields
   end

   def initialize(name. *fields)
     @@name=name,to_s
     @@fields=
     attr_accessor * @@fields=fields.map {|f| f.downcase.to_sym } # *
(to_args) does not work...
     return @content= # or Hash
   end
end

1. Subclassing Array is not a good idea. The implementation of Array is optimised for speed, and this causes all sorts of problems when you subclass it. True to a lesser extent to all the "primitive" data classes.

2. All your objects of type MyStruct will share a common @@fields and @@name. This is presumably not what you want; it's just a slightly odd thing about @@ vars. (Which is why they are not used much, I think.)

3. This looks rather like an Openstruct. Have you seen this (in the standard library)? Might be exactly what you need.

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

Hi
Perhaps its nice to make an own class:
- Here is my code, to get an idea what I'm thinking of,
please add / correct, tell me what could be done better!

thanks!!
- Opti

class MyStruct < Array
   def self.fields
     @fields
   end

   def initialize(name. *fields)
     @@name=name,to_s
     @@fields=[]
     attr_accessor * @@fields=fields.map {|f| f.downcase.to_sym } # * (to_args) does not work...
     return @content=[] # or Hash
   end
end

# Thats the goal:
A=MyStruct("person", :name, :age)
A.name # "person" # or "A", if name=nil --> how is that possible?
A.fields # => :name, :age
a=A.new("Max", 22)
A.members.length # 1
a # => ["Max", 22] # simple array
a.fields # no method ## OK, not on object!
a.name # => "Max"
a[:name] # => "Max"
a.find "Max" => :name