Why cant there be classes inside methods in Ruby?

前端 未结 4 1204
天涯浪人
天涯浪人 2021-02-19 18:29

Can I create Ruby classes within functions bodies ? I seem to be getting error which tells me its not allowed but I think it should be as classes are too objects here.



        
相关标签:
4条回答
  • 2021-02-19 18:34

    The question is about creating classes, but in the comment you talk about creating anonymous objects. Not the same thing.

    If you need anonymous object, you can always do Object.new. If you need simple struct-like container, you should take a look at Struct class. With it, you can do something like:

    def foo
      anon_obj = Struct.new(:prop1, :prop2).new
      anon_obj.prop1 = 123
      anon_obj.prop2 = 'bar'
    
      return anon_obj
    end
    

    BTW, Ruby is a strongly typed language. But it is a dynamic typed as well, and you can't expect it to behave like static-typed.

    0 讨论(0)
  • 2021-02-19 18:37

    you can create classes, but you cannot assign constants from inside a method.

    this example works:

    class A
      def a
        b = Class.new
        def b.xxx
          "XXX"
        end
        b
      end
    end
    
    a = A.new.a
    p a         # #<Class:0x7fa74fe6cc58>
    p a.xxx     # "XXX"
    
    0 讨论(0)
  • 2021-02-19 18:56
    class A
      def method
        self.class.const_set :B, Class.new {
          def foo
            'bar'
          end
        }
      end
    end
    
    A.new.method
    A::B.new.foo # => 'bar'
    

    However, why do you want to assign a constant inside a method? That doesn't make sense: constants are constant, you can only assign to them once which means you can only run your method once. Then, why do you write a method at all, if it is only ever going to be run once, anyway?

    0 讨论(0)
  • 2021-02-19 19:01

    You can create classes from within methods and assign them to a constant, as in the following

    class A
      def create_class class_name
        new_class = Class.new
        new_class.send :define_method, :speak do
          "Hi, There"
        end
        Object.const_set class_name, new_class
      end
    end
    
    A.new.create_class "Harry"
    h = Harry.new
    puts h.speak  # responds => "Hi, There"
    

    because a class name as in String is just a constant in ruby unlike many other languages.

    0 讨论(0)
提交回复
热议问题