週刊とっしーぱんち

昭和生まれのブロガーが綴る、全力脱力系雑記帳

Opalを使ってJavaScriptにデータを受け渡すとき思いついたやりかた

こんにちは!

RubyのコードをJavaScriptに変換してくれるGem「Opal」について、引き続きいろいろ遊ばせてもらっています。

今回は、データの受け渡し方をもう一工夫できないかなあという模索をしている記事です。

自分で作ったRubyオブジェクトをJavaScriptに渡すには

ドキュメントを読んでると、Opalが対応しているものは、いい感じにJavaScriptに変換してくれるようです。

opalrb.com

自分が作ったクラスもいい感じに変換してみました。

まずこんなふうなクラスを作ってみて

class TestData
  attr_accessor :num, :str,  :data_hash, :data_array

  def initialize (num, str, data_hash, data_array)
    @num= num
    @str = str
    @data_hash = data_hash
    @data_array = data_array
  end

end

Opalから呼び出すメソッドを書き

      def self.test_data()
        TestData.new(1, '2', {test: 1, test2: "test_str"}, [1, "2", 3])
      end

JavaScriptから呼びます

let d = Opal.Test.$test_data();
console.log(d.num);
console.log(d.num);
console.log(d.data_hash.$fetch('test2','')); 
console.log(d.data_array[0]);

こんな感じで取れます。ハッシュのところだけ少し注意が必要で、以下のように書くとエラーになります。

let d = Opal.Test.$test_data();
console.log(d.data_hash['test_data']); // undefinedと出ちゃう。

JSONでデータを渡すという選択肢

OpalでRubyとJavaScriptの橋渡しをする上で、メソッドを介したデータのやりとりはたくさん発生するでしょう。

らそこでハッシュのときだけfetchと書かなくてはと意識しておくのは、少し大変です。

そこで、Ruby側のコードを少し変えてJSONで返したらどうだろうという案を思いつきました。

def self.test_data()
  JSON.generate(
    num: 1,
    str: '2',
    data_hash: {test: 1, test2: "test_str"},
    data_array: [1, "2", 3] )
end

そうすると、JavaScript側でHashもこんなふうに扱うことができます。

let d = JSON.parse(Opal.Test.$now2());
console.log(d.num);
console.log(d.str);
console.log(d.data_hash.test);
console.log(d.data_array[0]);

好みの問題もあると思いますが、個人的にはこっちのほうが書き方が素直に感じます。

もちろんfetch()メソッドが必要なときもあるのですが、必要な時にだけ使えるようになっていることが好みです。

データをJavaScript側に渡すときはJSONデータで、というのがよさそうですが、これの弱点はJSON.generateのところです。

JSON.generateの引数はハッシュのオブジェクトなので、最初に作ったクラスがうまく活用できていないのですよね。

自分で作ったクラスオブジェクトをJSON化できたら一番美しい

やりかたを調べているところですが、たぶんクラスのインスタンスメソッド作って、インスタンス変数をハッシュオブジェクトにしていけばいけるのかな?とか妄想だけしている状態です。

と、今回はここまで。すこし疲れたのでこちらは次回の実験とします😀

では、また!