Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
Ruby automatically promotes a Fixnum to a Bignum when the value is too large to be held in a Fixnum. This is very sweet of it, but is also a gigantic pain in the rear end when you're doing bitwise operations where you want bits to fall on the floor. Is there any way to disable this, so that you can do normal integer-based bitwise operations?

Adbot
ADBOT LOVES YOU

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

derdewey posted:

Just a thought, how about testing the object with object.kind_of?(Bignum) or object.kind_of(Fixnum)? That way you know what bitmask to use. But ya, I think ruby's magical transformations can get in the way when you're doing something 'fancy'.

Well, all that I'm trying to do is implement the Jenkins one-at-a-time hashing algorithm. It's a very simple algorithm (here's how it would work if auto-conversion was disabled):

code:
   key.to_s.each_byte{ |b|
      hash += b.to_i
      hash += (hash << 10)
      hash ^= (hash >> 6)
   }

   hash += (hash << 3)
   hash ^= (hash >> 11)
   hash += (hash << 15)
Obviously it's the left-shifts that are making my puny regular integer into a super-integer.

If I could just xor the top-half of the Bignum with itself, that would work. But I'm not quite sure how I would go about doing that.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Popcorn Sutton posted:

Why is it breaking tables?

Thanks again for the help guys, no idea what i'd do without you. (Probably sit in #ruby on freenode and beg for help.

Also, for those of you who might play poxnora I'm coding a really awesome ruby app for our upcoming project GOONMALL.

You don't have a 'do' to go along with your 'while'. Also, while loops aren't very ruby idiomatic. You could try something like this instead:

code:
0.upto(500) { |idx|
   fout.puts "Enable-Mailbox -Identity NETADMIN.COM #{a[idx]}-Database Mailbox Database"
}

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
Two dirt-simple Ruby questions:

1) Let's say that I have a string that's "ENTRY9_blahblah". I need to pull out that 9 as an integer. There must be a better way to do this than either
code:
str.unpack("xxxxxa").to_s.to_i
or
code:
str[5] - 48
but because I'm stupid I have no idea what that way is.

2) I have a bunch of numbers stored as fixed-width strings in hex. For example, I'll have "12345678abcdef01" which I want to extract as 1 number with a value of 0x12345689, 1 number with a value of 0xabcd and 1 more number with a value of 0xef01. Currently I'm doing this:
code:
first_num = str[0..7].to_i(16)
second_num = str[8..11].to_i(16)
third_num = str[12..15].to_i(16)
But again, that seems really stupid. There must be a correct way to do this, right?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Hop Pocket posted:

There might be a simpler shorthand for regexes, but you would want to use a regex instead of unpack to do this.

Cool, thanks. I would probably do
code:
(/ENTRY(\d?)/.match(str))[1].to_i
Is there an easy way to find out in irb which method is faster in these situations? I'd like to know that the performance difference is for regex v. unpack v. anything else. And while we're on the subject, does Ruby use the old-style (and much faster) Bell Labs DFA regex algorithm or the weird (and slower) perl-style algorithm?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

drjrock_obgyn posted:

So unpack might be the fastest, but marginally. I'd use the regex for readability.

Hrm, interesting. I'd not played with benchmark before. I found out that my ugly-looking current approaches are actually the fastest by a long shot:

code:
[twitch@varial]$ cat ./b.rb
#!/usr/bin/ruby 

require 'benchmark'
include Benchmark

reps = 50000
str = "ENTRY9_laalalala"
str2 = "12345678abcdef01"
bm(20) do |x|
    x.report('Slice-and-subtract') {
        reps.times { a = str[5] - 48 }
    }

    x.report('Regex') {
        reps.times { a = str.match(/ENTRY(\d)/)[1].to_i }
    }

    x.report('Array ranges') {
        reps.times {
            a = str2[0..7].to_i(16)
            b = str2[8..11].to_i(16)
            c = str2[12..15].to_i(16)
        }
    }

    x.report('Unpack') {
        reps.times {
            a = str2.unpack("aaaaaaaa").join.to_i(16)
            b = str2.unpack("xxxxxxxxaaaa").join.to_i(16)
            c = str2.unpack("xxxxxxxxxxxxaaaa").join.to_i(16)
        }
    }
end

[twitch@varial]$ ./b.rb
                          user     system      total        real
Slice-and-subtract    0.050000   0.000000   0.050000 (  0.052927)
Regex                 0.160000   0.000000   0.160000 (  0.165503)
Array ranges          0.250000   0.000000   0.250000 (  0.257308)
Unpack                0.690000   0.000000   0.690000 (  0.709527)
Edit: Thanks, updated to reflect multiple runs
VVVVVVVVVVVVVVVVVVVVVVVVVV

Plastic Jesus fucked around with this message at 19:12 on Jul 20, 2008

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
Is it possible to load the code for a lambda from a file? I want to do this:

quote:

[twitch@varial]$ cat blah.test
puts "helu from the test"
[twitch@varial]$ irb
>> a = lambda { File.read("blah.test") }
=> #<Proc:0x0036707c@(irb):1>

and be able to just invoke 'a' like I would if I did this:

quote:

a = lambda { puts "helu from the test" }

But this is what happens:

quote:

>> a.call
=> "puts \"helu from the test\"\n"

I have a fairly ugly work-around, but I really want to be able to attach a method to an object at runtime, with the code for that method stored in a flat file.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

skidooer posted:

code:
a = lambda { load('/path/to/script.rb') }
a.call

That rules, but 1) there will be a file open/close every time it's invoked and 2) you can't pass args to Kernel.load :(

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

skidooer posted:

code:
code = File.read('/path/to/script.rb')
# => "puts \"Hello, #{name}\""

a = lambda { |name| eval(code) }
a.call('Plastic Jesus')

w00t, thank you. I now feel dim, but thanks.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Edit: Grrrrrrrrrr...nevermind, fixed it. Problem was NoScript.

Plastic Jesus fucked around with this message at 23:12 on Jan 19, 2011

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
I want to use the Linked In gem, but my app also uses Omniauth. Omniauth requires a newer version of oauth than the Linked In gem specifies, and Linked In specifies an exact version rather than '>='. This is easy to fix locally, but it'll break when I push to Heroku since Heroku will download the linkedin gem. Is there any clean way to supply a gemfile when pushing to Heroku?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

enki42 posted:

I had the exact same problem, and fixed it locally and forked the linked in gem and pointed it to my own git repository. You can use mine if you like:

code:
git://github.com/ryanbrunner/linkedin.git
My branches are a bit of a mess though, if you use "new_search" oauth should play nicely with omniauth. Gemfiles take git repositories with no problems, just use:

code:
gem 'linkedin', :git => 'git://github.com/ryanbrunner/linkedin.git', :branch => 'new_search'
To be honest, I think someone needs to take over the linkedin gem. I've had these commits open in a fork request for months now and the gem is starting to get seriously out of date.

Thanks for this. I have no clue why it didn't occur to me to use github but it didn't. Wait, right, it's because I'ma deeply stupid man.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
What's the correct RESTful way to do a site-wide search? That is, the search itself will cover multiple models and I'm not quite sure what the "right" route is. Should it just be application#search? That seems strange.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

BonzoESC posted:

For a generic search, I'd probably make the controller "Searches" or "SiteSearch", talking to a "SiteSearch" model that handles interaction with ThinkingShinx or whatever engine you end up using.

I created a controller and view for search, but I don't see why it needs a model. I could be wrong about this, as I'm usually wrong about these things.

ThinkingSphinx is out because Heroku doesn't support it, but I'm looking at WebSolr as an alternative.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Pardot posted:

Also check out index tank. I haven't used them myself but it looks great.

That looks like it's geared toward searching documents rather than databases. Which is awesome, but I need the ability to quickly search a crapload of database columns spread across several tables. I also like that I can test Solr locally for free during dev.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Soup in a Bag posted:

Read up on Hash.new in the core docs. If you give the Hash a default object or block, that object will be used or that block evaluated whenever you reference a non-existent key.

Unfortunately there can be a problem using a default object:

Instead you'd use the default block form:

This needs further explanation because it's really confusing when you start programming ruby:

code:
ruby-1.9.2-head > a = Hash.new([])
 => {} 
ruby-1.9.2-head > a[:foo] << "wtf"
 => ["wtf"] 
ruby-1.9.2-head > a[:bar] << "really?"
 => ["wtf", "really?"] 
ruby-1.9.2-head > a[:bar]
 => ["wtf", "really?"] 
ruby-1.9.2-head > a[:foo].object_id
 => 2168798500 
ruby-1.9.2-head > a[:bar].object_id
 => 2168798500 
Giving an empty array to Hash.new() doesn't mean that you'll get a new, empty array every time you access an undefined key in the hash, it means that each undefined key in the hash will get a reference to the same array. However, if you do something like what Soup In a Bag says then you get what you'd expect:

code:
ruby-1.9.2-head > b = Hash.new { Array.new }
 => {} 
ruby-1.9.2-head > b[:foo] = "oh"
 => "oh" 
ruby-1.9.2-head > b[:bar] = "ok."
 => "ok." 
ruby-1.9.2-head > b[:foo].object_id
 => 2165102360 
ruby-1.9.2-head > b[:bar].object_id
 => 2165094280 
The first form says "hey, I'm creating an object that can be used by any new key." The second form says "hey, every time a new key is created run this code that creates a new, empty Array object for it." This is even more confusing because the following works exactly like you'd think:

code:
ruby-1.9.2-head > c = Hash.new(0)
 => {} 
ruby-1.9.2-head > c[:foo] += 1
 => 1 
ruby-1.9.2-head > c[:bar] += 1
 => 1 
The difference is that with Hash.new(0) the '0' is considered a literal, not a reference. And it's not that numbers are magic, look:

code:
ruby-1.9.2-head > d = Hash.new('oh?')
 => {} 
ruby-1.9.2-head > d[:foo] += " really?"
 => "oh? really?" 
ruby-1.9.2-head > d[:bar] += " I guess I get it?"
 => "oh? I guess I get it?" 
The principle of "least surprise" unfortunately for newcomers means "least surprise to people who know the language well." This is actually a good thing, though, since Ruby does behave as you'll expect, just not right off the bat.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

smug forum rear end in a top hat posted:

I'm starting to use OmniAuth. If I'm understanding correctly, it only connects with the Facebook API when a user needs to be authorized. Can I pull data from a user's facebook profile at will with OmniAuth?

(I'm working from Ryan Bates' set of OmniAuth Railscasts here.)

You send a request to Facebook to access a user's account on his behalf. Facebook asks the user if that's cool. If the user says OK you get back a token and a secret to use later to access the user's info. OmniAuth handles negotiating with Facebook and gets the user token/secret for you. It's then on you to use those credentials (in conjunction with your application's key and secret) to actually access the data. There are lots of Facebook gems out there to handle the heavy lifting for you.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
You really, really, really don't want to execute shell commands from a script that accepts user-supplied data. I also doubt that you'd want to be able up/down a network interface or change its IP address via a web application.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

BonzoESC posted:

The Post model isn't the Group membership:


code:
class Group < ActiveRecord::Base
  has_many :users, through: :group_memberships
  has_many :posts
end

class GroupMembership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

class Post < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

class User < ActiveRecord::Base
  has_many :groups, through: :group_memberships
  has_many :posts
end


I think he wants this
code:
class Group < ActiveRecord::Base
  belongs_to :user # a user owns a group when he starts it
  has_many :posts
  has_many :members, :through => :group_memberships
end

class GroupMembership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

class Post < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

class User < ActiveRecord::Base
  has_many :group_memberships # groups the user belongs to
  has_many :groups # groups the user started
  has_many :posts
end
The belongs_to macro gets tricky with users and groups because you immediately think "Oh hey, users belong to groups because they're members of groups," which is not what belongs_to means.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
I've run into something in Rails 3 that I don't understand. Assume I have the following models:

code:
class User < ActiveRecord::Base
  has_many :email_providers
end

class EmailProviders < ActiveRecord::Base
  belongs_to :user
end
Then if I want to create a new user in the user controller this will not work:
code:
@user = User.new
@user.email_providers.push EmailProvider.create do |prov|
   prov.email_address = params[:user][:email_address]
end

@user.save
@user.email_providers.last.email_address will be nil. The following, however, works:

code:
@user = User.new
eprov = EmailProvider.create do |prov|
  prov.email_address = params[:user][:email_address]
end
@user.email_providers.push eprov
@user.save
With that @user.email_providers.last.email_address is correct. Is this expected behavior?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

skidooer posted:

If we add brackets, your code is equivalent to this:

code:
@user.email_providers.push(EmailProvider.create) do |prov|
   prov.email_address = params[:user][:email_address]
end

Do'h, thanks. I assumed that it was something syntactical I was missing from staring at the same code for too long. Thanks also for the tip of adding a setter method, which may be useful for more than 1 reason.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Stup posted:

Thanks for all your help! Off to do a little reading now.

BTW you probably don't need a custom validator, For instance, you can just do
code:
validates_uniqueness_of :nickname, :scope => [:team_id]
That's totally a blind guess at what your models look like but hopefully you get the idea. Unless I'm misunderstanding what you're trying to do it's unlikely you'll want or need to get a list of all team members and compare their nicknames to the new nick; let AR handle that for you.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Obsurveyor posted:

code:
def cant_have_more_than_one_guard
  guards = members.select { |m| m.gen_pos == 'Guard' }
  errors.add_to_base "Can't have more than 1 guard" unless guards.count <= 1
end
Here is some less ugly code. I am too tired to figure out the validation thing though. :)

Here is some more efficient code (calls COUNT() in SQL rather than selecting and iterating through each member).

code:
def cant_have_more_than_one_guard
  errors.add_to_base "Can't have more than 1 guard" unless members.where(:gen_pos => 'Guard').size <= 1
end

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
I'm using highcharts and would like to render the charts via a partial called from my view and it's not working at all. I have a partial called '_chart.js.erb' that contains the javascript to create and render the chart, but if I do:
code:
= render :partial => 'chart'
from within contacts/show.html.haml I get
code:
Missing partial contacts/chart with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=>[:html]...
Notice that :formats does not include :js. If I do
code:
= render :js => 'chart'
I get
code:
undefined method `formats' for nil:NilClass
which I think is related. Finally, if I do
code:
= render :partial => 'chart.js'
I just get javascript rendered as text (I understand why and this isn't the correct thing to do, just including it for the sake of completeness). I'm clearly doing things wrongly, I just don't know what I should be doing. Note that I don't want to put the chart-rendering code in the contacts/show.html.haml view because I want to be able to render it from other views.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
In case anyone's run into the same javascript partial rendering problem I posted about earlier, I managed to fix it. I put the javascript in a haml file and did a "render :partial => 'chart.js'" and now everything is fine. Something doesn't feel right about having to supply the ".js" but whatever it's good enough for now.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
My application serves profile images and I don't want any schlub who knows the URL for the image to be able to load it. That part is easy, I control access in Photos#show and use send_data (photos are stored in the DB btw). However it looks like browsers aren't caching the photos, which makes page load times unnecessarily long. This feels like a stupidly basic question, but what should I do here to speed up loads? Is there any way I can provide an etag before the controller method is invoked and I have to deal with the database hit?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Pardot posted:

A couple of things to try, more or less in order:

* Make sure the Cache-Control header is something like Public, max-age: bignumber. I'd have to look up the exact syntax.
* make sure last-modified header is set.
Those two might be all you need. They are set for actual static files, but since you're sending the data yourself, they probably aren't set any more. Once you have those you'll get browser caching again
* try http://rtomayko.github.com/rack-cache/ and also this technique https://gist.github.com/9395
However if you're not careful with this you'll lose the user checking.

Alternatively, you could store all the photos in S3, and just generate short-lived urls on demand if they have permissions. That's what I would probably do, since anything I write that has uploads just puts them in s3 to begin with. Since local disk is ephemeral ;)

Thanks for this. I'm hesitant to provide a max-age since the images do change and not on a predictable basis. I now set Etag and Last-Modified in PhotoController#show but unless the browser sends a HEAD request before each GET are those going to matter?

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

A MIRACLE posted:

I think SASS is pretty neat. But do I have to leave the Sass CLI listener open and watching my .scss files for diffs, or can the interpreter just use them un-converted by virtue of having the .scss extension? Windows dev here.

They have to be converted to regular CSS on-disk. You don't strictly have to leave the converter running all the time, that's just a nice-to-have when you're testing/tweaking your scss mods.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Bob Morales posted:

What's going on here?

code:
@promotion.evaluations[1..99].each do |subsequent_evaluation|
 ...
 ...
 ...
end
Why wouldn't you just do @promotion.evaluations.each? Coming from a C background, that would be an array of evaluations (which could be arrays themselves)

It means 'loop through indexes 1 to 99 in the array @promotion.evaluations'. for the c folk this would be
code:
for(int i = 1; i <= 99; ++i){
   subsequent_valuation = promotion->evaluations[i];
   ...
}

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.
So...Rails 3.1 is scheduled to drop tomorrow. Anyone have a decent set of links for getting up to speed on things? So far I've not touched it and have just cobbled together info from the links in this 3 month old blog post. In particular I'd appreciate thorough write-ups of asset pipelines and engines.

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

A MIRACLE posted:

looked it up. heroku has pretty extensive documentation.

Not idling worker dynos is really loving annoying. I realize it's only $34/month but it's dumb to wind down the free web dyno while leaving the worker dyno up, doing absolutely nothing.



Edit: So this happened. Read about it here.

Plastic Jesus fucked around with this message at 04:18 on Aug 31, 2011

Adbot
ADBOT LOVES YOU

Plastic Jesus
Aug 26, 2006

I'm cranky most of the time.

Smol posted:

Is there a good way to make action caching worth with multiple formats? As far as I can tell, Rails doesn't seem to care about the Accept header when determining cache keys, so when I enable action caching, Rails will always return the response to the first format that was requested (all formats will have the same cache key).

There is a :cache_path parameter, but I'm not sure what would be the recommended way to use it in this case, or if it helps at all.

With Action Caching it should just work out of the box, e.g. cache JSON separately from HTML or XML. With Page Caching I have no idea what would happen, but you probably don't want page caching...

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply