오픈 소스 모험: 에피소드 61: Opal Ruby가 클래스를 나타내는 방법

19768 단어 rubyjavascript
이전 에피소드에서 우리는 Opal Ruby가 기본 데이터 유형을 나타내는 방법을 확인했습니다. 이제 몇 가지 클래스를 정의하고 컴파일 대상을 살펴보겠습니다.

간단한 사람 클래스



매우 간단한 클래스부터 시작하겠습니다.

class Person
  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def to_s
    "#{@first_name} #{@last_name}"
  end
end

person = Person.new("Alice", "Ruby")
puts "Hello, #{person}!"
nil


래퍼를 사용하면 다음과 같이 엄청나게 컴파일됩니다.

Opal.queue(function(Opal) {/* Generated by Opal 1.5.0 */
  var self = Opal.top, $nesting = [], $$ = Opal.$r($nesting), nil = Opal.nil, $klass = Opal.klass, $def = Opal.def, person = nil;

  Opal.add_stubs('new,puts');

  (function($base, $super) {
    var self = $klass($base, $super, 'Person');

    var $proto = self.$$prototype;

    $proto.first_name = $proto.last_name = nil;


    $def(self, '$initialize', function $$initialize(first_name, last_name) {
      var self = this;


      self.first_name = first_name;
      return (self.last_name = last_name);
    }, 2);
    return $def(self, '$to_s', function $$to_s() {
      var self = this;

      return "" + (self.first_name) + " " + (self.last_name)
    }, 0);
  })($nesting[0], null);
  person = $$('Person').$new("Alice", "Ruby");
  self.$puts("Hello, " + (person) + "!");
  return nil;
});


몇 가지를 풀어 보겠습니다.
  • $$('Person')는 지속적으로 조회합니다.
  • 모든 메서드는 JavaScript와의 충돌을 줄이기 위해 $ 접두어로 정의되므로 .$initialize , .$to_s , .$new , .$puts 등이 있습니다
  • 인스턴스 변수는 놀랍게도 직접 ​​매핑되므로 first_name 인스턴스 변수는 .first_name
  • this는 ES6 이전 자바스크립트self에서와 같이 메서드 입력 시 로컬 변수this에 할당되어 많이 변경됩니다. 이 기술은 실제로 손으로 작성한 ES6 이전 JavaScript 코드에서도 많이 사용되었습니다. 요즘은 드물어요.

  • 계승


    Person에서 상속해 봅시다.

    class Person
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def to_s
        "#{@first_name} #{@last_name}"
      end
    end
    
    class Cat < Person
      def to_s
        "Your Majesty, Princess #{super}"
      end
    end
    
    cat = Cat.new("Catherine", "Whiskers")
    puts "Hello, #{cat}!"
    nil
    


    이것은 가독성이 좋지 않을 것입니다.

    Opal.queue(function(Opal) {/* Generated by Opal 1.5.0 */
      var self = Opal.top, $nesting = [], $$ = Opal.$r($nesting), nil = Opal.nil, $klass = Opal.klass, $def = Opal.def, $send2 = Opal.send2, $find_super = Opal.find_super, cat = nil;
    
      Opal.add_stubs('new,puts');
    
      (function($base, $super) {
        var self = $klass($base, $super, 'Person');
    
        var $proto = self.$$prototype;
    
        $proto.first_name = $proto.last_name = nil;
    
    
        $def(self, '$initialize', function $$initialize(first_name, last_name) {
          var self = this;
    
    
          self.first_name = first_name;
          return (self.last_name = last_name);
        }, 2);
        return $def(self, '$to_s', function $$to_s() {
          var self = this;
    
          return "" + (self.first_name) + " " + (self.last_name)
        }, 0);
      })($nesting[0], null);
      (function($base, $super) {
        var self = $klass($base, $super, 'Cat');
    
    
        return $def(self, '$to_s', function $$to_s() {
          var $yield = $$to_s.$$p || nil, self = this;
    
          delete $$to_s.$$p;
          return "Your Majesty, Princess " + ($send2(self, $find_super(self, 'to_s', $$to_s, false, true), 'to_s', [], $yield))
        }, 0)
      })($nesting[0], $$('Person'));
      cat = $$('Cat').$new("Catherine", "Whiskers");
      self.$puts("Hello, " + (cat) + "!");
      return nil;
    });
    


    보시다시피 생성된 코드는 완전히 읽을 수 없으며 JavaScript OOP 기능을 거의 사용하지 않습니다. ES6 이전의 JavaScript OOP는 지옥이었고 그것이 Opal이 목표로 삼은 것입니다. ES6+를 대상으로 하는 것이 상황을 많이 개선할지 확신할 수 없습니다.

    자세히 살펴보면 yield에 대한 일부 지원을 볼 수 있습니다.

    지금까지의 이야기



    All the code is on GitHub .

    다음에 온다



    다음 에피소드에서는 Ruby2JS와 Opal Ruby를 비교하는 방법을 살펴보겠습니다.

    좋은 웹페이지 즐겨찾기