mufid-github-io-2czqvc.txt (3841B)
1 { 2 fidz 3 } 4 5 [1]Mufid's Code blog 6 7 • [2]RSS 8 9 [4][ ] 10 • [5]Blog 11 • [6]Archives 12 13 In Ruby, Everything is Evaluated 14 15 Jul 10th, 2016 | [7]Comments 16 17 So if i write 18 19 1 def hello 20 2 puts 'world' 21 3 end 22 23 It will evaluate def, to which Ruby will “create a method named hello in global 24 scope, with puts ‘world’ as a block”. We can change “global scope” to any 25 object we want. 26 27 1 class Greeting 28 2 def hello 29 3 puts 'world' 30 4 end 31 5 end 32 33 The class “Greeting” is actually EVALUATED, NOT DEFINED (e.g. In Java, after we 34 define a signature of a class/method, we can’t change it, except using 35 reflection). So actually, we can put anything in “Greeting” block, like 36 37 1 class Greeting 38 2 puts "Will define hello in greeting" 39 3 def hello 40 4 puts 'world' 41 5 end 42 6 end 43 44 Save above script as “test.rb” (or anything) and try to run it. It will show 45 “Will define hello in greeting” EVEN you don’t call “Greeting” class or “hello” 46 class or you don’t even need to instantiate “Greeting” class. This language 47 feature allows meta programming, like what we see in Rails. 48 49 This time i will use Class Attribute within active support. If you ever run 50 Rails, you should have it, but you can gem install active_support if you don’t. 51 52 1 require 'active_support/core_ext/class/attribute' 53 2 54 3 module Greeting; end 55 4 56 5 class Greeting::Base 57 6 58 7 class_attribute :blocks 59 8 60 9 def hello(name) 61 10 self.blocks[:greeting].call(name) 62 11 self.blocks[:hello].call(name) 63 12 end 64 13 65 14 protected 66 15 def self.define_greeting(sym, &blk) 67 16 self.blocks ||= {} 68 17 self.blocks[sym] = blk 69 18 end 70 19 end 71 20 72 21 class Greeting::English < Greeting::Base 73 22 define_greeting :greeting do |who| 74 23 puts "Hi #{who}, Ruby will greet you with hello world!" 75 24 end 76 25 define_greeting :hello do |who| 77 26 puts "Hello World, #{who}!" 78 27 end 79 28 end 80 29 81 30 class Greeting::Indonesian < Greeting::Base 82 31 define_greeting :greeting do |who| 83 32 puts "Halo kakak #{who}, Ruby akan menyapamu dengan Halo Dunia!" 84 33 end 85 34 define_greeting :hello do |who| 86 35 puts "Halo dunia! Salam, #{who}!" 87 36 end 88 37 end 89 38 90 39 x = Greeting::English.new 91 40 x.hello "Fido" 92 41 # Hi Fido, Ruby will greet you with hello world! 93 42 # Hello World, Fido! 94 43 x = Greeting::Indonesian.new 95 44 x.hello "Fido" 96 45 # Halo kakak Fido, Ruby akan menyapamu dengan Halo Dunia! 97 46 # Halo dunia! Salam, Fido! 98 99 Previously i want to move the class attribute logic to above code, but after i 100 see the [8]Active Support code, it is pretty complex, so i just require it : / 101 102 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103 104 Previously, i posted [9]this in Reddit 105 106 Posted by Mufid Jul 10th, 2016 107 108 [10]Tweet 109 110 [11]« Using Class with Generics <T> Without the T in C# [12]Cara Googling » 111 112 Comments 113 114 Please enable JavaScript to view the [13]comments powered by Disqus. 115 116 Copyright © 2021 - Mufid - Powered by [14]Octopress 117 118 119 References: 120 121 [1] https://mufid.github.io/blog/ 122 [2] https://mufid.github.io/atom.xml 123 [5] https://mufid.github.io/blog/ 124 [6] https://mufid.github.io/blog/blog/archives 125 [7] https://mufid.github.io/blog/2016/ruby-class-evaluation/#disqus_thread 126 [8] https://github.com/rails/rails/blob/e35b98e6f5c54330245645f2ed40d56c74538902/activesupport/lib/active_support/core_ext/class/attribute.rb 127 [9] https://www.reddit.com/r/ProgrammerTIL/comments/4s2vmr/ruby_til_in_ruby_everything_is_evaluated/ 128 [10] http://twitter.com/share 129 [11] https://mufid.github.io/blog/2016/generic-type-csharp/ 130 [12] https://mufid.github.io/blog/2016/how-to-google/ 131 [13] http://disqus.com/?ref_noscript 132 [14] http://octopress.org/