Tip/Trick: a bit of Javascript in Ruby
Author |
Message |
wtd
|
Posted: Fri Sep 23, 2005 10:30 pm Post subject: Tip/Trick: a bit of Javascript in Ruby |
|
|
In Javascript, what look like properties of an object can also be accessed as if they were part of an associative array (hash).
Is the same as:
And we can go the other way.
Now, Ruby doesn't work the same way normally, but we can hack it rather simply to do the same thing.
Now, in Ruby, when we have something like:
It's a call of the method "bar" on the object "foo".
So, how can we turn that into a hash lookup?
Well, let's look at what happens when a method is called that doesn't exist.
code: | insaneones@ubuntu:~ $ irb
irb(main):001:0> class Foo
irb(main):002:1> def bar
irb(main):003:2> "hello"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> Foo.new.bar
=> "hello"
irb(main):007:0> Foo.new.baz
NoMethodError: undefined method `baz' for #<Foo:0xb7df3b4c>
from (irb):7
irb(main):008:0> |
We get an exception, which makes sense.
So, how can we deal with this?
Wel, Ruby's very dynamic nature means that it shouldn't surprise anyone to find out there is a way. If we define a method called method_missing which takes a method name and the arguments sent to it, that method will be called when an undefined method is called.
Behold.
code: | class Foo
def initialize
@internal = {}
end
def method_missing(name, *args)
name = name.to_s
if name =~ /\=$/
@internal[name.sub /\=$/, ''] = args.first
else
@internal[name]
end
end
end |
Questions? |
|
|
|
|
|
Sponsor Sponsor
|
|
|
timmytheturtle
|
Posted: Sun Sep 25, 2005 12:34 am Post subject: (No subject) |
|
|
I got a question, since I'm still learning Ruby what is this ~ /\=$/. I havent seen it before |
|
|
|
|
|
wtd
|
Posted: Sun Sep 25, 2005 1:07 am Post subject: (No subject) |
|
|
timmytheturtle wrote: I got a question, since I'm still learning Ruby what is this ~ /\=$/. I havent seen it before
Is a regular expression. Consider the
As being like:
For regular expressions.
The actual regular expression is:
This is a pattern. The backslash escapes the = sign. As it turns out, I didn't need the backslash. Backslash is meant to escape characters which otherwise would have some significant meaning.
The $ indicates the end of the string.
The pattern therefore specifies an equals sign at the end of a string.
This is the match operator which checks if a string matches the pattern (regular expression). |
|
|
|
|
|
timmytheturtle
|
Posted: Sun Sep 25, 2005 1:11 am Post subject: (No subject) |
|
|
Alright makes sense, thanks wtd. This language is starting to become easier than I first expected |
|
|
|
|
|
wtd
|
Posted: Sun Sep 25, 2005 1:36 am Post subject: (No subject) |
|
|
Nifty. |
|
|
|
|
|
Tony
|
Posted: Mon Sep 26, 2005 11:15 am Post subject: (No subject) |
|
|
nifty indeed. Catching "missing" Rails pages |
|
|
|
|
|
Tony
|
Posted: Wed Nov 16, 2005 4:57 pm Post subject: (No subject) |
|
|
today I was building integrated help feature for my applicatioin. Quite simple, it's just a load of (?) links that would call help/category/topic controller/method/id, and that should render appropriate information. Hardcoding reference information into a controller is a pretty horrible idea.
Ruby: |
def method_missing(name, *args)
category = name
topic = params[:id]
begin
info = YAML::load(File::open("helpinfo/" + category.to_s + ".yml").read)
if info[topic].nil? then
@topic = "topic not found"
@content = "sorry"
else
@topic = info[topic]["topicname"]
@content = info[topic]["content"]
end
rescue => fault
@topic = "help file not found"
@content = "sorry"
end
render :action => 'viewtopic'
end
|
So now when you call help/foo/bar, Rails will attempt to locate foo.yml file, and find bar entry within the file. viewtopic action then renders the page.
Furthermore if there's a complicated topic to be explained, an appropriate method could be created (it will no longer be missing) and another set of instructions will be used to render a specialized page.
Ofcourse the above code looks out for missing files and entries, so looking up an arbitrary entry will not break the application. |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
wtd
|
Posted: Wed Nov 16, 2005 5:42 pm Post subject: (No subject) |
|
|
Ruby: | YAML::load(File::open("helpinfo/" + category.to_s + ".yml") |
And we clean that up a bit...
Ruby: | YAML::load(File::open("helpinfo/#{category}.yml") |
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
|
|