Skip to content

Instantly share code, notes, and snippets.

@yuroyoro
Created January 31, 2012 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuroyoro/1709748 to your computer and use it in GitHub Desktop.
Save yuroyoro/1709748 to your computer and use it in GitHub Desktop.
RubyでOGNLっぽく、文字列で表現されたプロパティにアクセスするための適当なナニか
#!/usr/bin/env ruby
# RubyでOGNL(Object Notation Graph Language)っぽく、
# 文字列で表現されたプロパティにアクセスするための
# 適当なナニか。
#
#
# Ognl.new('foo_string').apply(foo)
# => object notation graph language!!
#
# Ognl.new('foo_array[1]').apply(foo)
# => 2
#
# Ognl.new('foo_hash[:a]').apply(foo)
# => ooo
#
# Ognl.new('nested_obj.foo_string').apply(foo)
# => ( ゚∀゚)o彡°おっぱい!おっぱい!
#
# Ognl.new('nested_obj.foo_array[1]').apply(foo)
# => 456
#
# Ognl.new('nested_obj.foo_hash[:a]').apply(foo)
# => oppai!!
#
# ognl.new('foo_array[3]').apply(foo)
# => #<Foo:0x10e0366a0>
#
# Ognl.new('foo_array[3].foo_string').apply(foo)
# => ( ゚∀゚)o彡°おっぱい!おっぱい!
#
# Ognl.new('foo_array[3].foo_array[1]').apply(foo)
# => 456
#
# Ognl.new('foo_array[3].foo_hash[:a]').apply(foo)
# => oppai!!
#
# Ognl.new('foo_hash[:foo2]').apply(foo)
# => #<Foo:0x10e0366a0>
#
# Ognl.new('foo_hash[:foo2].foo_string').apply(foo)
# => ( ゚∀゚)o彡°おっぱい!おっぱい!
#
# Ognl.new('foo_hash[:foo2].foo_array[1]').apply(foo)
# => 456
#
# Ognl.new('foo_hash[:foo2].foo_hash[:a]').apply(foo)
# => oppai!!
#
class Ognl
attr_accessor :expression
def initialize(expression)
@expression = expression
end
def parse(e)
e.split(/(\.|\[[^\]]+\])/).reject{|exp| exp == "." || exp.nil? || exp.empty?}
end
def apply(target)
exps = parse(expression)
exps.inject(target){|obj, exp|
if exp =~ /\[([^\]]+)\]/
key = $1
key = case key
when /^\d+$/ then key.to_i
when /^:(.+)/ then $1.to_sym
else key.to_s
end
obj.send("[]", key) if obj.respond_to? "[]"
else
obj.send(exp) if obj.respond_to? exp
end
}
end
end
class Foo
attr_accessor :foo_array, :foo_hash, :nested_obj, :foo_int, :foo_string
def initialize
@foo_array = [1, 2, 3]
@foo_hash = {:a => "ooo", :b => "pai"}
@foo_int = 123
@foo_string = "object notation graph language!!"
end
end
foo = Foo.new
puts "Ognl.new('foo_string').apply(foo)"
puts "=> #{Ognl.new('foo_string').apply(foo)}"
puts ""
puts "Ognl.new('foo_array[1]').apply(foo)"
puts "=> #{Ognl.new('foo_array[1]').apply(foo)}"
puts ""
puts "Ognl.new('foo_hash[:a]').apply(foo)"
puts "=> #{Ognl.new('foo_hash[:a]').apply(foo)}"
puts ""
foo2 = Foo.new
foo2.foo_int = 999
foo2.foo_string = "( ゚∀゚)o彡°おっぱい!おっぱい!"
foo2.foo_hash[:a] = "oppai!!"
foo2.foo_array[1] = 456
foo.nested_obj = foo2
foo.foo_array << foo2
foo.foo_hash[:foo2] = foo2
puts "Ognl.new('nested_obj.foo_string').apply(foo)"
puts "=> #{Ognl.new('nested_obj.foo_string').apply(foo)}"
puts ""
puts "Ognl.new('nested_obj.foo_array[1]').apply(foo)"
puts "=> #{Ognl.new('nested_obj.foo_array[1]').apply(foo)}"
puts ""
puts "Ognl.new('nested_obj.foo_hash[:a]').apply(foo)"
puts "=> #{Ognl.new('nested_obj.foo_hash[:a]').apply(foo)}"
puts ""
puts "Ognl.new('foo_array[3]').apply(foo)"
puts "=> #{Ognl.new('foo_array[3]').apply(foo)}"
puts ""
puts "Ognl.new('foo_array[3].foo_string').apply(foo)"
puts "=> #{Ognl.new('foo_array[3].foo_string').apply(foo)}"
puts ""
puts "Ognl.new('foo_array[3].foo_array[1]').apply(foo)"
puts "=> #{Ognl.new('foo_array[3].foo_array[1]').apply(foo)}"
puts ""
puts "Ognl.new('foo_array[3].foo_hash[:a]').apply(foo)"
puts "=> #{Ognl.new('foo_array[3].foo_hash[:a]').apply(foo)}"
puts ""
puts "Ognl.new('foo_hash[:foo2]').apply(foo)"
puts "=> #{Ognl.new('foo_hash[:foo2]').apply(foo)}"
puts ""
puts "Ognl.new('foo_hash[:foo2].foo_string').apply(foo)"
puts "=> #{Ognl.new('foo_hash[:foo2].foo_string').apply(foo)}"
puts ""
puts "Ognl.new('foo_hash[:foo2].foo_array[1]').apply(foo)"
puts "=> #{Ognl.new('foo_hash[:foo2].foo_array[1]').apply(foo)}"
puts ""
puts "Ognl.new('foo_hash[:foo2].foo_hash[:a]').apply(foo)"
puts "=> #{Ognl.new('foo_hash[:foo2].foo_hash[:a]').apply(foo)}"
puts ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment