Fun Board


Go Back   Fun Board » Moderated usnet disscussion » Programming » Ruby

Ruby Everything about programming in Ruby language.

Tags: ,


 
 
LinkBack Thread Tools Display Modes
Old 15th December 2010, 22:48   #1 (permalink)
Dave Birch
Guest
 
Posts: n/a

Hi,

I'm trying to implement a simple parser and quite likely going about it
the wrong way.

I would like to be able to include a bit of ruby code in a string, which
is saved to a field in a database. When the string is retrieve from the
database at a later stage, I want to parse it for code and evaluate the
code, substituting the result value into the string.

I've been trying to do something like this:


module Substitutable
@other_word = "other word"
proc = Proc.new{}
String.class_eval do
define_method :to_s do
self.gsub(/<code>(.*?)<\/code>/) do |match|
code = match.scan(/<code>(.*)<\/code>/).flatten.first
eval(code, proc.binding)
end
end
end
end


# If I then create a class and include Substitutable, I get the
following output

class Tester


include Substitutable

def say
@word = "hello"
'<code>@other_word</code>'.to_s # => "other word"
'<code>@word</code>'.to_s # => ""
'<code>"hard coded word"</code>'.to_s # => "hard coded word"
end
end

Tester.new.say

So I know that conceptually passing the a proc to the eval method does
enable me to set an instance variable out of the scope of the new to_s
method. But I cannot work out how to get the scope of the class within
which Substitutable has been "include"d. I've tried various things
like...

a) creating an "proc" method within the class that returns a proc object
b) creating a "@proc" instance variable within the class

...but with no luck.

Is what I'm trying to do possible?

Thanks very much in advance...

Dave
--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #2 (permalink)
Dave Birch
Guest
 
Posts: n/a

Hi,

Thought I'd try one poke to see if I could resurrect this. I'm still
stumped on how to solve this.

Thanks in advance.

Regards,
Dave
--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #3 (permalink)
Marnen Laibow-Koser
Guest
 
Posts: n/a

Dave Birch wrote:
> Hi,
>
> I'm trying to implement a simple parser and quite likely going about it
> the wrong way.
>
> I would like to be able to include a bit of ruby code in a string, which
> is saved to a field in a database. When the string is retrieve from the
> database at a later stage, I want to parse it for code and evaluate the
> code, substituting the result value into the string.


You are aware of the serious security problems with this, right?

[...]
> But I cannot work out how to get the scope of the class within
> which Substitutable has been "include"d.


Perhaps you should use the Module#included callback to register it.

Best,
--*
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #4 (permalink)
Dave Birch
Guest
 
Posts: n/a

Hi Marnen

Thanks very much for the reponse.

Marnen Laibow-Koser wrote:
> Dave Birch wrote:


> You are aware of the serious security problems with this, right?


Yes, this isn't a public-facing site, and there will be no front-end
access to the database that will generate and store the code.

> [...]
>> But I cannot work out how to get the scope of the class within
>> which Substitutable has been "include"d.

>
> Perhaps you should use the Module#included callback to register it.


I will look at this - thanks again for the tip.

Regards,
Dave


>
> Best,
> --*
> Marnen Laibow-Koser
> http://www.marnen.org
> marnen@marnen.org


--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #5 (permalink)
Marnen Laibow-Koser
Guest
 
Posts: n/a

Dave Birch wrote:
> Hi Marnen
>
> Thanks very much for the reponse.
>
> Marnen Laibow-Koser wrote:
>> Dave Birch wrote:

>
>> You are aware of the serious security problems with this, right?

>
> Yes, this isn't a public-facing site, and there will be no front-end
> access to the database that will generate and store the code.


Then you shouldn't need to do this in the first place. If there's no
frontend access to the DB, presumably that means that the app itself is
generating the code. If so, then it can keep it as a method in a live
object rather than writing it to the database and opening up a security
hole.

>
>> [...]
>>> But I cannot work out how to get the scope of the class within
>>> which Substitutable has been "include"d.

>>
>> Perhaps you should use the Module#included callback to register it.

>
> I will look at this - thanks again for the tip.
>
> Regards,
> Dave
>
>
>>
>> Best,
>> --*
>> Marnen Laibow-Koser
>> http://www.marnen.org
>> marnen@marnen.org


Best,
--*
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #6 (permalink)
Dave Birch
Guest
 
Posts: n/a

Marnen Laibow-Koser wrote:
> Dave Birch wrote:
>> Hi Marnen
>>
>> Thanks very much for the reponse.
>>
>> Marnen Laibow-Koser wrote:
>>> Dave Birch wrote:

>>
>>> You are aware of the serious security problems with this, right?

>>
>> Yes, this isn't a public-facing site, and there will be no front-end
>> access to the database that will generate and store the code.

>
> Then you shouldn't need to do this in the first place. If there's no
> frontend access to the DB, presumably that means that the app itself is
> generating the code. If so, then it can keep it as a method in a live
> object rather than writing it to the database and opening up a security
> hole.
>


To give you a bit of background to this - I've got a "macro" that is
generating a bunch of reports. The reports contain lines like "the
number of people in this group are X and they have spent a total of Y on
your product this year". The problem is, I can't substitute X and Y for
their real values at the time the macro runs, because I don't know what
filters the user will apply when viewing the reports. So I need a way
to do the calculations and substitute in the values when the user views
the report, and to recalculate these each time the user changes the
filter (e.g. show me only people older than 30).

So unless I'm missing something, I can't keep a live object.

It's a rails app, and the controller will be pulling together a
"@results" variable, but will not necessarily know what kinds of stats
need to be pulled from it. That's why i'd like to be able to do things
like "the number of people in this group are <code>@results.size</code>
and they spent <code>@results.collect(&:spend).sum</code> on your
product this year".

Doees this make sense?

>>
>>> [...]
>>>> But I cannot work out how to get the scope of the class within
>>>> which Substitutable has been "include"d.
>>>
>>> Perhaps you should use the Module#included callback to register it.

>>
>> I will look at this - thanks again for the tip.
>>
>> Regards,
>> Dave
>>
>>
>>>
>>> Best,
>>> --*
>>> Marnen Laibow-Koser
>>> http://www.marnen.org
>>> marnen@marnen.org

>
> Best,
> --*
> Marnen Laibow-Koser
> http://www.marnen.org
> marnen@marnen.org


--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #7 (permalink)
Seebs
Guest
 
Posts: n/a

On 2010-01-15, Dave Birch <thisisdaveb@gmail.com> wrote:
> To give you a bit of background to this - I've got a "macro" that is
> generating a bunch of reports. The reports contain lines like "the
> number of people in this group are X and they have spent a total of Y on
> your product this year". The problem is, I can't substitute X and Y for
> their real values at the time the macro runs, because I don't know what
> filters the user will apply when viewing the reports. So I need a way
> to do the calculations and substitute in the values when the user views
> the report, and to recalculate these each time the user changes the
> filter (e.g. show me only people older than 30).


Check with a rails group, but I'm pretty sure you'll find that you can,
in fact, do this natively in rails without the security hole.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Old 15th December 2010, 22:48   #8 (permalink)
Josh Cheek
Guest
 
Posts: n/a

[Note: parts of this message were removed to make it a legal post.]

On Fri, Jan 15, 2010 at 8:42 AM, Dave Birch <thisisdaveb@gmail.com> wrote:

> To give you a bit of background to this - I've got a "macro" that is
> generating a bunch of reports. The reports contain lines like "the
> number of people in this group are X and they have spent a total of Y on
> your product this year". The problem is, I can't substitute X and Y for
> their real values at the time the macro runs, because I don't know what
> filters the user will apply when viewing the reports. So I need a way
> to do the calculations and substitute in the values when the user views
> the report, and to recalculate these each time the user changes the
> filter (e.g. show me only people older than 30).
>
> So unless I'm missing something, I can't keep a live object.
>
> It's a rails app, and the controller will be pulling together a
> "@results" variable, but will not necessarily know what kinds of stats
> need to be pulled from it. That's why i'd like to be able to do things
> like "the number of people in this group are <code>@results.size</code>
> and they spent <code>@results.collect(&:spend).sum</code> on your
> product this year".
>
>

I don't really see the benefit of storing the template in the database, but
here is what I came up with.

require 'rubygems'
require 'activerecord'
require 'sqlite3'
require 'erb'


# documentation at http://www.sqlite.org/lang_createtable.html
db = SQLite3:atabase.new( 'store_and_execute_strings.db' )
db.execute <<-__________________________________________________
CREATE TABLE IF NOT EXISTS reports (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
title Text,
template TEXT
);
__________________________________________________

db.execute <<-__________________________________________________
CREATE TABLE IF NOT EXISTS groups (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
name STRING
);
__________________________________________________

db.execute <<-__________________________________________________
CREATE TABLE IF NOT EXISTS people (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
group_id INTEGER,
money_spent DOUBLE,
age INTEGER
);
__________________________________________________


# documentation at http://api.rubyonrails.org/classes/A...cord/Base.html
# for other (better, depending on your needs) documentation, see
http://guides.rubyonrails.org/active..._querying.html
#
http://guides.rubyonrails.org/association_basics.html
#
http://guides.rubyonrails.org/active...callbacks.html
ActiveRecord::Base.establish_connection :adapter =>
'sqlite3' ,
:host =>
'localhost' ,
:database =>
'store_and_execute_strings.db' ,
:username =>
'root' ,
assword => ''

class Report < ActiveRecord::Base
def generate( &init )
dup.instance_eval {
instance_eval &init if init
ERB.new( template , 0 , "%<>" ).result( binding )
}
end
end

class Group < ActiveRecord::Base
has_many eople
end

class Person < ActiveRecord::Base
belongs_to :group
end



# here is an example, as I understand your criteria

text_for_report = "the number of people in this group are <%= @people.length
%> and they have spent " \
"a total of $<%= @people.inject(0) { |sum,person|
sum+person.money_spent.to_f } %> " \
"on your product this year"

Report.new( :template => text_for_report , :title => 'Customer Summary'
).save

doctors = Group.new :name => 'doctors'
doctors.save

(1..10).each do |num|
money , age = num , 20+num*5
doctors.people.build( :money_spent => money , :age => age ).save
end

customer_summary = Report.find_by_title 'Customer Summary'

puts customer_summary.generate { @people =
doctors.people }
puts customer_summary.generate { @people = doctors.people.all :conditions =>
'money_spent <= 5' }
puts customer_summary.generate { @people = doctors.people.all :conditions =>
'age < 40' }

 
Old 15th December 2010, 22:48   #9 (permalink)
Josh Cheek
Guest
 
Posts: n/a

[Note: parts of this message were removed to make it a legal post.]

Hmm, formatting looks really bad up on my email, here is a pastie for it
http://pastie.org/private/taieshtr0nwhnv1unkrjq

 
Old 15th December 2010, 22:48   #10 (permalink)
Dave Birch
Guest
 
Posts: n/a

Josh, thanks VERY much for the response. I'm going to digest it and
will let you know once I've got it working.

Have a good weekend.

Cheers,
Dave

Josh Cheek wrote:
> Hmm, formatting looks really bad up on my email, here is a pastie for it
> http://pastie.org/private/taieshtr0nwhnv1unkrjq


--
Posted via http://www.ruby-forum.com/.

 
Old 15th December 2010, 22:48   #11 (permalink)
Marnen Laibow-Koser
Guest
 
Posts: n/a

Dave Birch wrote:
> Josh, thanks VERY much for the response. I'm going to digest it and
> will let you know once I've got it working


No. Better to go for a solution without the security hole. It should be
possible, but ask on the Rails list instead.

>
> Have a good weekend.
>
> Cheers,
> Dave
>
> Josh Cheek wrote:
>> Hmm, formatting looks really bad up on my email, here is a pastie for it
>> http://pastie.org/private/taieshtr0nwhnv1unkrjq


Best,
--*
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
--
Posted via http://www.ruby-forum.com/.

 
 

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post

something strange with CLASS and SCOPE

Phillip Gawlowski wrote: > (Actually, the class instance gets initialized, and not the instance > variables, strictly speaking.) It's worth mentioning that a class is itself an object (an instance of class Class), and therefore has its own instance variables. class QQ # at this point, the...
Tony Tony Ruby 3 15th December 2010 22:48

loses scope?

On Thu, Dec 24, 2009 at 6:59 AM, Jeff Shantz <rubyforum@jeffshantz.com> wro= te: > Jes=FAs Gabriel y Gal=E1n wrote: >> irb(main):001:0> class A >> irb(main):002:1> end >> =3D> nil >> irb(main):005:0> a =3D 3 >> =3D> 3 >> irb(main):006:0> A.class_eval do >> irb(main):007:1*...
Roger Pack Ruby 9 15th December 2010 22:47

Problem trying to get a constant with correct scope

Walton Hoops wrote: > irb(main):012:0> A::B.foo do > irb(main):013:1* puts eval('BAR') > irb(main):014:1> end > 1 > => nil > > Done. A more experienced Rubist may be able to do it without eval, but > that works.
Alexandre Mutel Ruby 10 15th December 2010 22:47

Binding#eval __LINE__ and __FILE__ in Ruby 1.9.1

Ok. One last question in today's debugging for 1.9 session. Using Bindging#eval, __LINE__ and __FILE__ always appear the same: binding.eval('__FILE__') #=> "(eval)" binding.eval('__LINE__') #=> 1 Do we not want the __LINE__ and __FILE__ of the binding call in the binding's context? That...
Intransition Ruby 0 15th December 2010 22:45

What us binding objects

At 2009-10-29 07:08AM, "Nike Mike" wrote: > What is the usage of binding objects Principally, to specify the context in which you want to evaluate some code See: http://www.ruby-doc.org/core/classes/Kernel.html#M005922 and: http://rosettacode.org/wiki/Eval#Ruby for an example. --...
Nike Mike Ruby 3 15th December 2010 22:44

Scope Missunderstanding

Mex Noob Yes wrote: > i got a module x and then a class z and inside this class i do a > Net::HTTP call and it looks for it inside module x ... and i am > clueless... > > i get uninitialized constant ModuleX::Net::HTTP Almost certainly you forgot the "require 'net/http'" in the actualy code...
Vic P.h. Ruby 3 15th December 2010 22:44

Kernel.eval("local_variables",binding) bug in Ruby 1.9

Please send this to ruby-core@ On Sep 17, 2009, at 16:30 , Howard Yeh wrote: > Hi, > > My ruby runtime is "ruby 1.9.1p0 (2009-01-30 revision 21907) " > > Kernel eval works for these cases: >
Howard Yeh Ruby 1 15th December 2010 22:43

Is Passing a Binding with Parameters Possible?

Caleb Clausen wrote: > On 9/4/09, John Sikora <john.sikora@xtera.com> wrote: >> Space Ship Traveller wrote: >>> I like lmgtfy: >>> >>> http://lmgtfy.com/?q=Binding+of_caller >> >> Thanks for the link. No one has ever accused me of being particularly >> adept at conducting a web search. >>
John Sikora Ruby 7 15th December 2010 22:43

Who is the MySQL/Ruby binding gem author?

On Jul 27, 6:49 pm, Tony Arcieri <t...@medioh.com> wrote: > > > On Sun, Jul 26, 2009 at 11:58 PM, Luis Lavena <luislav...@gmail.com> wrote: > > If you're the author of mysql gem published on RubyForge, please > > contact me over this mailing list or directly to luislavena at gmail > > dot...
Luis Lavena Ruby 4 15th December 2010 22:41

eval(string) scope ?

Hi, I had the idea to create a walkthrough sessions for users, printing statements, then executing one by one. I find that eval on separate strings doesn't put values in the same scope, so any statement using an earlier value throws ReferenceError. Here's a minimal session:
Jocke P JavaScript 3 13th December 2010 12:33

Scope Resolution Operator

Hello I have a question about the Scope Resolution Operator ::. Here is my scenario. I have an authentication class that performs all the needed login, registration and permissions levels. There is obviously some DB interaction.
Scott Johnson PHP 8 13th December 2010 10:08

All times are GMT +1. The time now is 09:10.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2