how can get proc content using Opalrb parser - ruby

I need to get the content of a proc send to js by Opal ruby.
I am only using the static version of Opal, Opal-native, opal-parser.
how can I proceed ?
def parse_proc params
#### how can I get proc content?
end
def touch(&proc)
parse_proc proc
end
b=box()
c=circle()
b.touch do
b.color(:red)
c.x=200
end

I found a solution I think there must be an better way but it works :
def analysis_of_proc params
the_proc_conent_is=`the_proc_conent_is = #{params}.toString();`
puts the_proc_conent_is
end
def my_proc(&proc)
analysis_of_proc proc
proc.call
end
my_proc do
a="hello"
b="world"
def add_word fist, second
return fist+" "+second
end
add_word a,b
end

Related

Ruby - Singleton module with each. Returning a value gives an Enumerator. How can I get the value instead?

Example code:
module Creatures
class << self
def to_h
{
squirtle: {full_name: 'Squirtle T. Turtle'},
pikachu: {full_name: 'Pikachu B. Pikachu'}
}
end
def keys
to_h.keys
end
def collect
to_h.keys.collect
end
def each
to_h.keys.each
end
end
end
module CompanionHelper
def get_companion_creature_experience(companion_data)
Creatures.each do |creature|
return companion_data[creature]["#{creature}_experience".to_sym] if companion_data.has_key?(creature)
end
end
end
include CompanionHelper
companion_data = {squirtle: {squirtle_experience: 8000}}
get_companion_creature_experience(companion_data)
Forgive me if the example is contrived. The original code is from the insurance world but I can't copy and paste it :)
The crux of the problem is I want to use Creatures.each in another module, pass it a block, and have it work just like Creatures.keys.each would work (i.e. w/ the given example companion data I get 8000 for get_companion_creature_experience(companion_data).
Currently I get Enumerator instead.
Problem is that to_h.keys.each returns Enumerator which does not expect any arguments. Pass a block inside each since you want to use it:
def each &block
to_h.keys.each &block
end
Or you can yield it:
def each
to_h.keys.each do |k|
yield k
end
end

creating method on fly as a parameter while calling singleton method

How's it possible in ruby ?
class Test
# Creating singleton method
def self.some_singleton_method(param1)
puts param1
end
end
# calling singleton method by creating method on fly as a parameter to it
Test.some_singleton_method def method_name(some_param)
# do something
end
## method_name
I've tried many places looking around, can't come up with an idea how's it's working.
Thanks!
It is possible, since def is keyword, that creates new method in current scope, which is Object since you're calling it on the "top" level, i.e. not inside any class. Starting from Ruby 2.1, def returns method name as a symbol, so your code is actually equivalent to
name = def method_name(some_param)
// do something
end
Test.some_singleton_method(name) # outputs "method_name"
EDIT: Thanks to Cary Swoveland for clarification that def is actually a keyword and not a method.
Here are two ways to do that.
#1
class Test
def self.doit(m)
send(m) yield
end
end
Test.doit(:hello) do
puts 'hi'
end
#=> :hello
Test.new.hello
#=> "hi"`.
#2
class Test
def self.doit(str)
eval(str)
end
end
Test.doit "def hello; puts 'hi'; end"
#=> :hello
Test.new.hello
#=> "hi"`.

Using ruby blocks with method calls

The following code works perfectly.
#doc = open(link) { |f| Hpricot(f) }
But I want to use the following code, which doesn't seem to play well with the Hpricot block (e.g. #doc is a TempFile object, not a Hpricot document object)
#doc = resolve_link(link) { |f| Hpricot(f) }
def resolve_link(link)
begin
return open(link)
rescue
logger.debug("#{$!} for link #{link}")
raise Exceptions::ErrorResolvingLink.new("Cannot resolve link #{link}.")
end
end
Any idea how I can get the second version of the code to work?
You're calling resolve_link with a block but you're not passing that block down to open. Try this instead:
def resolve_link(link, &block)
begin
return open(link, &block)
#...
You have to use yield to invoke the block.
See this answer for a very simple example:
Blocks and yields in Ruby
So something along the lines
def resolve_link(link)
...
yield ( some_value_to_pass_to_the_block )
...
end
Should work.

How to create a method like ".find_by_something_and_something_else" using Ruby?

Using Ruby I know you can get pretty creative with how you name your methods. For instance in rails you have .find_by_this_and_that.
How can I do this?
Example:
def get_persons_with_5_things
res = []
persons.each do |person|
if person.number_of_things == %MAGICALLY GET THE NUMBER 5 FROM FUNCTION NAME%
res << person
end
end
return res
end
I'm not even sure how you call this kind of things so any pointers would be appreciated.
I'm a little confused by your example. If you define the method with the hardcoded 5 in the method name, then you don't need to magically figure it out inside the body of the method. If you want to do something dynamic with method missing, it would be something like this:
def method_missing(name, *args)
if name.to_s =~ /get_persons_with_(\d+)_things/
number_of_things = $1.to_i
res = []
persons.each do |person|
if person.number_of_things == number_of_things
res << person
end
end
return res
else
return super(name, *args)
end
end
[EDIT (Jörg W Mittag)]: This is a more Rubyish way of implementing that same method:
def method_missing(name, *args)
return super unless name.to_s =~ /get_persons_with_(\d+)_things/
number_of_things = $1.to_i
return persons.select {|person| person.number_of_things == number_of_things }
end
super without any arguments just passes the original arguments along, no need to pass them explicitly
an early return guarded by a trailing if or unless expression greatly clears up control flow
all the each iterator does, is select items according to a predicate; however, there already is an iterator for selecting items: select
Ruby has different meta programming techniches to do this kind of stuff.
First we need our variable method
class DB
def get_persons_with_x_things(x)
res = []
persons.each do |person|
if person.number_of_things == x
res << person
end
end
return res
end
end
define_method
If there is a finite number of x's. We could use define_method to create all this methods. define_method creates a method. The first argument is the name of the method, the seccond argument or the given block is the stuff, which get's executed when the method is called.
This way, you don't realy create such method's, but It will look for the user if he calls it, as if it existed. But if the user relies on Object#methods and such, he will never see your inifinite number of fake methods.
class DB
99.times do |i|
define_method("get_persons_with_#{i}_things") do
get_persons_with_x_things(i)
end
end
end
method_missing
If there is an infinite numbor of x's method_missing would be better suited for this Task. If someone tries to call a method which does not exist, method_missing is executed instead. The first argument for method_missing is the method name as symbol, the following arguments are the original arguments.
class DB
def method_missing(name, *args)
case name.to_s
when /^get_persons_with_(\d+)_things$/
get_persons_with_x_things($1.to_i)
else
super(name, *args)
end
end
end
method_missing and send
To not use static regexe would be even cooler. But this could have some security implications. The method send I use here, calls a method by it's name.
class DB
def method_missing(name, *args)
name.to_s=~ /\d+/
# always be carefull with $ variables, they are global for this thread, so save everything as fast as you can
new_name= "#{$`}x#{$'}"
number= $1.to_i
if method_defined?(new_name)
send(new_name, number)
else
super(name, *args)
end
end
end
you can do a lot of things like this with method missing:
Ruby Docs
StackOveflow method_missing
Have a look at Ruby's callbacks specially method_missing.

Ruby access to symbol "invoked by"

I want to (efficiently) get the symbol an aliased method is called with at runtime. A direct efficient access to a stack frame object of some sort to get it would be the fantasy.
ie:
class Foo
def generic_call(*args)
puts("generic_call() was called by using #{???}")
end
alias :specific_call1 :generic_call
alias :specific_call2 :generic_call
end
Foo.new.specific_call1
Foo.new.specific_call2
the result I'd want
generic_call() was called by using specific_call1()
generic_call() was called by using specific_call2()
class Foo
def generic_call()
puts "generic call was called by #{caller[0][/in `([^']+)'/, 1]}"
end
def specific_call1() generic_call end
def specific_call2() generic_call end
end
Foo.new.specific_call2 # Prints: generic call was called by specific_call2
This will however not work if you use alias to create specific_callN from generic_call because methods created by alias are actually a copy of the original method - they don't actually call the original method (which is why you can freely redefine the original without affecting the alias).
A code snippet to get the current method name:
module Kernel
private
# Defined in ruby 1.9
unless defined?(__method__)
def __method__
caller[0] =~ /`([^']*)'/ and $1
end
end
end
There's no built-in way to do this. You can kind of hack it like:
def current_method_name
caller[0].split('`').last.split('\'')[0]
end
Maybe, you want something like this?
class Object
def named_alias(name, generic_name)
([Class, Module].include?(self.class) ? self : self.class).class_eval do
define_method(name) { |*args| send(generic_name, name, *args) }
end
end
end
class Foo
def generic_call(f, *args)
puts("generic_call() was called by using #{f} with #{args}")
end
# def specific_call1(*args)
# generic_call(:specific_call1, *args)
# end
named_alias(:specific_call1, :generic_call)
named_alias(:specific_call2, :generic_call)
end
Foo.new.specific_call1
Foo.new.specific_call2
Disclaimer: I don't know Ruby, I've just Googled how one performs currying there, then adapted the code a bit.

Resources